opensocial-as3-clientライブラリを使ってみた(1)

前回のエントリーで見たように、opensocialとflashの連携ライブラリはいくつかあるようですが、1つずつ調査開始です。ぱっと見、Flash CS3に対応していそうなopensocial-as3-clientから見ていきます。

** opensocial-as3-clientライブラリを用意する google codeにソースコードがあります。

| http://code.google.com/p/opensocial-as3-client/ |<

*** Downloadする ダウンロードの箇所にはファイルがないのでsubversionを用いて下記のようにダウンロードします。subversionから取得します。subversionクライアントをお持ちでない場合は、まずはそちらをインストールして下さい。現在の最新タグは2009-04-18-0.8-M3(以降M3と呼ぶ)とされています。今回はこのM3を使います。

|| svn export http://opensocial-as3-client.googlecode.com/svn/tags/2009-04-18-0.8-M3/ opensocial-as3-client-M3 ||<

*** opensocial-flashsdk.jsを設置 opensocial-as3-clientで使うjavascriptをお好きなところへアップロードします。このJSはのちほどGadget XMLから読み込みます。

| src/org/opensocial/client/jswrapper/javascript/opensocial-flashsdk.js |< opensocial-as3-clientライブラリを利用しOpenSocialコンテナとの通信をJavaScript APIに選択した場合、FLASHはこのJSを介してOpenSocialコンテナとの通信を行います。M3タグではRestful Protocolは実装されていないようようなので必然的にJavaScript APIを選択することになります。 opensocial-flashsdk.jsは、opensocial.flashを思いっきり拡張しています。これはOpenSocialコンテナ側が用意するJSを汚染することになるのでちょっと気になりますね。

*** ドキュメント docの下にAS側、JS側と分かれて配置されてます。下記にサンプルもあるので先に見ておくと理解が深まります。

| sample/flash/SampleApp.as(flex派はsample/flex/SampleApp.as) |< ドキュメントによると、opensocial-as3-clientライブラリを含めたSWFはAS-SideのJsWrapperClientをブリッジとしてJavaScript APIをラップしたJS-Sideのopensocial-flashsdk.jsと通信を行うとのことです。図にするとこんな感じです。

*** 未実装なところ Restful API周りがNot implemented yetです。

*** Security.allowDomain Security.allowDomainはどこで実行しているのかが気になります。

| src/org/opensocial/client/jswrapper/JsWrapperClient.as 120: // TODO: The security need to be configured. 121: Security.allowDomain("*"); |< 定番のワイルドカード。以前紹介したアレをするのもいいかもしれないです。 | Security.allowDomain(ExternalInterface.call("function() { return location.hostname; }")); |<

** 作ってみる 今回はOWENERのマイミク一覧を取得してみます。opensocial-as3-clientに付属するopensocial-flashsdk.jsはopensocial.flashのembedFlashの問題を修正しているので、swfobjectを使う必要はありません。

*** Gadget XML Gadget側はこんな感じです。先に述べたようにopensocial.flash.embedFlashは拡張されており、もはや今までのopensocial.flash.embedFlashではありません。

|| <?xml version="1.0" encoding="UTF-8" ?> <![CDATA[

]]> ||<

*** Flashに指定するDocumentClass Flashのドキュメントクラスに指定するクラスです。ポイントとなる箇所にコメントを付けてあります。

|| package { import flash.display.Sprite; import org.opensocial.client.base.Collection; import org.opensocial.client.base.DataRequest; import org.opensocial.client.base.IdSpec; import org.opensocial.client.base.Person; import org.opensocial.client.base.ResponseItem; import org.opensocial.client.core.GadgetsHelper; import org.opensocial.client.core.OpenSocialHelper; import org.opensocial.client.events.OpenSocialClientEvent; import org.opensocial.client.jswrapper.JsWrapperClient; import org.opensocial.client.util.FirebugPrinter; import org.opensocial.client.util.Logger; import org.opensocial.client.util.TracePrinter;

/ * opensocial-as3-clientを試す */ public class LibWork1 extends Sprite { //--------------------------------------------------------------------- // properties //--------------------------------------------------------------------- //----------------------------- // opensocial-as3-client //----------------------------- / * opensocial client which bridges JS-side and AS-side. */ private var _client:JsWrapperClient;

/**
 * Features helper for several sub-namespaces in the gadgets namespace.
 */
private var _gadgets:GadgetsHelper;

/**
 * Features helper for opensocial namespaces. 
 * This is the core namespace for the Opensocial API.
 */
private var _opensocial:OpenSocialHelper;

/**
 * Logger like a java.util.logging.Logger
 */
private var _logger:Logger;
//-----------------------------
//  for this sample application
//-----------------------------
/**
 * get person count per request
 */
private const GET_PERSON_COUNT:int = 10;

/**
 * people thumbnails
 */
private var _thumbnails:Array = [];

//---------------------------------------------------------------------
//  method
//---------------------------------------------------------------------
/**
 * constructor
 */
public function LibWork1() 
{
  /*
   * 付属のLoggerを設定
   */
  Logger.initialize(new TracePrinter());
  _logger = new Logger(LibWork1);

  /* 
   * clientを作成する。現在はJavaScript APIのみ
   * 引数にJavaScriptのnamespaceを指定可能だがとりあえずデフォルトで
   */
  _client = new JsWrapperClient("opensocial.flash");

  /*
   * 後述のstartメソッド実行後に送出されるイベントをリッスン
   */
  _client.addEventListener(OpenSocialClientEvent.CLIENT_READY,
      client_ReadyHandler);

  /*
   * ExternalInterfaceのセットアップなどを行う
   */
  _client.start();

  /*
   * swfのcontainerに定義されたgadgets.*の名前空間のJavaScript API
   * にアクセスするためのヘルパーを定義
   */
  _gadgets = new GadgetsHelper(_client);

  /*
   * swfのcontainerに定義されたopensocial.*の名前空間にあるJavaScript API
   * へアクセスするためのヘルパーを定義
   */
  _opensocial = new OpenSocialHelper(_client);  
}

/**
 * fetch people via JavaScript API
 * @param  start
 */
private function fetchPeople(start:int):void
{
  /*
   * OWNERのFriendsを表示してみる
   * 標準のAPIと若干違うので注意
   */
  var idSpec:IdSpec = IdSpec.newInstance(IdSpec.PersonId.OWNER, IdSpec.GroupId.FRIENDS, 1); 
  var params:Object = DataRequest.newPeopleRequestParams(start, GET_PERSON_COUNT);
  _opensocial.fetchPeople(idSpec, people_fetchCallback, params);
}

/**
 * render fetched pepole
 */
private function renderPeople():void
{
  // _thumbnailsを使って何かをしましょう
}

//---------------------------------------------------------------------
//  event handler
//---------------------------------------------------------------------
/**
 * event handler for OpenSocialClientEvent.CLIENT_READY
 * @param  event
 */
private function client_ReadyHandler(event:OpenSocialClientEvent):void
{
  /*
   * 準備OKになったらfirebug.cosoleへの吐き出しへ変更してみる
   */
  Logger.initialize(new FirebugPrinter());

  fetchPeople(0);
}

//---------------------------------------------------------------------
//  callback
//---------------------------------------------------------------------
private function people_fetchCallback(r:ResponseItem):void
{
  var c:Collection = r.getData();
  var arr:Array = c.getArray();
  for (var i:int = 0; i < arr.length; i++)
  {
    var p:Person = arr[i];
    _thumbnails.push(p.getThumbnailUrl());
  }

  if (c.getOffset() * GET_PERSON_COUNT < c.getTotalSize())
  {
    fetchPeople(c.getOffset() + 1);
  }
  else
  {
    renderPeople();
  }

  /*
   * mixi ではこの条件文ではだめ
   */
  /*
  if (c.getRemainingSize() > 0) {
    fetchPeople(c.getNextOffset());
  }
  */
}

} } ||<

** というわけでむりやりまとめ 他のライブラリでも同様かと思いますが、JavaScript APIを意識せずに記述できる点はFLASHERにとってうれしいことです。但し、今回使用したopensocial-as3-clientでは、JavaScript APIと記述方法に違いがあるので注意が必要です。 例をあげるとJavaScriptでJavaScript APIを利用したIdSpecオブジェクトの生成は以下のようになりますが

| var param = {}; param[opensocial.IdSpec.Field.USER_ID] = opensocial.IdSpec.PersonId.VIEWER; param[opensocial.IdSpec.Field.GROUP_ID] = "FRIENDS"; var idSpec = opensocial.newIdSpec(param); |< opensocial-as3-clientを利用したActionScriptでのIdSpecオブジェクトの生成は以下のようになります。 | var idSpec:IdSpec = IdSpec.newInstance(IdSpec.PersonId.OWNER, IdSpec.GroupId.FRIENDS, 1); |< JavaScript APIを直接使ったOpenSocialアプリケーションを開発していた技術者にとっては、このような各ライブラリごとの記述方法も学ぶ必要があるため出来るだけJavaScript APIと似た記述が出来るライブラリを使いたいところです。

*** _thumbnailsを使って何かした 上記コードの

| // _thumbnailsを使って何かをしましょう |< の箇所でスライドショーをしてみました。 | http://platform001.mixi.jp/view_appli.pl?id=1549 |< 今後、このブログを通じて機能拡張をして行くかも知れません。