OpenSocial + FLASHのライブラリ

OpenSocialでFLASHを使うに当たって、ライブラリはないもんかと探してみたところ、google codeにいくつかのプロジェクトが存在を確認しました。下記の上から2つまでが実際にファイルが上がっております。

どちらかというとflex向けかもしれません。

flash CS3とかでもいけるかもしれません。

なにもないかもしれません。
他にもflixiというライブラリがあります。

どれもまだざっとしか見ていないのですが、ActionScript側にもJavaScript APIと同様の構造を用意してあげて、Gadget XMLからJavaScript APIを呼ぶのと同じような感覚で実行して出来ますよ、というのが基本スタンスのようです。

とりあえず勝手に決めた本命はopensocial-as3-clientです。今度ちゃんと使い方とかまとめます。

でも、ActionScriptからだってライブラリ使わずにOpenSocial JavaScript APIを実行したいんだぜ、という人向けのチップスを思いついたので紹介します。たぶんまねしないほうがいいです。

FlashからJavaScript APIを実行したい

ところで、FlashからJavaScriptのalertを実行するには以下のようにすることで実行できます。

ExternalInterface.call("function() { alert('hoge');}");

もうお分かりですね。これを使えばいいんです。
まずは、なんのへんてつもないGadget XMLを用意。

Gadget XML
<?xml version="1.0" encoding="UTF-8" ?>
<Module>
  <ModulePrefs title="flash test" author="naoto koshikawa">
    <Require feature="opensocial-0.8" />
    <Require feature="views" />
    <Optional feature="content-rewrite">
      <Param name="include-urls"></Param>
      <Param name="exclude-urls">.*</Param>
      <Param name="include-tags"></Param>
      <Param name="expires">0</Param>
    </Optional>
  </ModulePrefs>
  <Content type="html">
  <![CDATA[
    <script src="<PathTo>prototype.js"></script>
    <script src="<PathTo>swfobject.js"></script>
    <div id="externalContainer">
      <h1>Alternative content</h1>
      <p><a href="http://www.adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" /></a></p>
    </div>
    <script type="text/javascript">
      function init() {
        swfobject.embedSWF(
          "<PathToYourSWF>", "externalContainer", "200", "200", "9.0.0",
          undefined,
          {}, // flashvars
          {
            quality : 'high',
            allowScriptAccess : 'always'
          }, // params
          {
            id : "externalswf"
          } // attributes
        );
      }
      gadgets.util.registerOnLoadHandler(init);
    </script>
  ]]>
  </Content>
</Module>
DocumentClass

そしてFlashのドキュメントクラスに指定するクラス

package
{
  import flash.display.Loader;
  import flash.display.Sprite;
  import flash.events.Event;
  import flash.events.MouseEvent;
  import flash.external.ExternalInterface;
  import flash.net.URLRequest;
  import flash.system.Security;
  import flash.text.TextField;
  import flash.text.TextFieldAutoSize;
  
  /**
   * アグレッシブなOpenSocial JavaScript APIの利用方法
   */
  public class Work extends Sprite
  {
    private var _txt:TextField;
    private var _loader:Loader;
    public function Work() 
    {
      Security.allowDomain(ExternalInterface.call("function() { return location.hostname }"));
      ExternalInterface.addCallback("loadImage", loadImage);
      
      _txt = new TextField();
      _txt.autoSize = TextFieldAutoSize.LEFT;
      _txt.text = "画像を取得";
      _txt.x = stage.stageWidth /2 - _txt.width / 2;
      _txt.y = stage.stageHeight /2 - _txt.height / 2;
      _txt.border = true;
      _txt.addEventListener(MouseEvent.CLICK, clickHandler);
      _txt.selectable = false;
      addChild(_txt);
      
      _loader = new Loader();
      _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
    }
    
    private function loadImage(url:String):void
    {
      _loader.load(new URLRequest(url));
    }
    
    private function clickHandler(event:MouseEvent):void
    {
      ExternalInterface.call(
          "function() {"
        + "  var req = opensocial.newDataRequest();"
        + "  req.add(req.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER), 'viewer');"
        + "  req.send(function(data) {"
        + "  if (data.hadError()) {"
        + "    alert(data.getErrorMessage());"
        + "  } else {"
        + "    var item = data.get('viewer');"
        + "    if (item.hadError()) {"
        + "    alert(item.getErrorMessage());"
        + "    } else {"
        + "    var viewer = item.getData();"
        + "    $('externalswf').loadImage(viewer.getField(opensocial.Person.Field.THUMBNAIL_URL));"
        + "    }"
        + "  }"
        + "  });"
        + "}"
      );
    }
    
    private function completeHandler(event:Event):void
    {
      _loader.x = stage.stageWidth /2 - _loader.width / 2;
      _loader.y = stage.stageHeight /2 - _loader.height / 2;
      addChild(_loader);
    }
  }
}

ちゃんとプロフィール画像が表示されました。でも保守しづらそうなにおいがぷんぷんしますね、すみません。次はもうちょっとちゃんと考えたエントリーを書きます。