umjammer です、 ソーシャルアプリの作り方の第三回になります。 ソーシャルアプリとして Mixi アプリを作成しましたが、単なるゲームを Mixi に持ってきただけではソーシャルな要素が全くなく、ソーシャルなプラットフォームを使う意味がありません。 このシリーズでは前回前々回にすでに出てきているようにハイスコア管理をソーシャル要素として使用します。アプリの内容がゲームですからソーシャルグラフ上でスコアを競ってもらいます。またできるだけ簡単に作ることを方針としていますので、一から API を実装するつもりはありません。Mixi はゲームに特化した API は公開していませんので、すでに世の中にあるソーシャルプラットフォームを探し出してきて使用します。 今回はゲームに特化したソーシャルプラットフォームとして今 iPhone で盛り上がりつつある OpenFeint を使用することにします。SPACE INVADERS INFINITY GENE も採用してますよ。
OpenFeint Logo


ここからがこのシリーズの一番の目玉になります! OpenFeint は iPhone 用に SDK をオープンソースで提供しています。今のところ Objective-C で書かれた iPhone 用しか存在しません。盛り上がっているソーシャルプラットフォームなのでぜひ使用したいものです。幸い SDK はオープンソースなのでプロトコルを解析してやれば他のプラットフォームでも動かすことが出来そうです。

OpenFeint プロトコル解析

iPhone 用の SDK にコンパイル時オプションとして -DDEBUG を設定してやります。あとソースを追っかけていくと最終的に NSURLConnection クラスを使用しているので通信メソッドに渡すパラメータなどを NSLog で出力させるようにします。そして iPhone 用に OpenFeint を使用したサンプルゲームを作成して、実際操作しながら機能に対する通信ログを取っていきます。OpenFeint SDK は UI も含めた膨大な機能を持っていますので、今回は OpenFeint に対するログインと、ユーザー操作、ハイスコア、アチーブメント機能あたりに絞って解析しました。 解析して分かったことは、OpenFeint API は REST を用いて API 認可には HMAC-SHA1 シグネチャの OAuth を使用しています。そしてデータとして XML を返します。JSON じゃないんですね。

REST & OAuth

OAuth はライブラリが公開されていますのでそれを使用します。簡単に使用するために軽くラップします。 http://code.google.com/p/umjammer/source/browse/trunk/vavi-apps-gae03/src/main/java/vavi/util/openfeint/OpenfeintOAuthUtil.java GAE/J 上ではホワイトリストの関係上 HTTPClient4 が使用できなかったのでその辺りを自作します。通信は OpenFeint API が https を使用しているため、頻繁にタイムアウトが起こります。GAE/J の API の URLFetch にはソケットのタイムアウト指定ができないため URLConnection を使用します。 http://code.google.com/p/umjammer/source/browse/trunk/vavi-apps-gae03/src/main/java/vavi/util/openfeint/GaeHttpClient.java

XML Binding

戻り値である XML の定義 XSD を OpenFeint は用意してくれていませんので、さきほど解析した実データの XML インスタンスを素に XSD を作ります。Castor というソフトウェアにその機能が備わっていますので使用します。ただしパッチが必要なのですが。 XML インスタンスから XSD を作成する ant のマクロ定義例

  <macrodef name="xml2xsd"
            description="Generate XML Schema from XML Instance.">
    <attribute name="in" />
    <attribute name="out" />
    <sequential>
      <java classname="org.exolab.castor.xml.schema.util.XMLInstance2Schema"
            fork="true">
        <classpath>
          <pathelement location="${dir.build}" />
          <path refid="run.class.path" />
          <fileset dir="${ant.home}/lib">
            <include name="*.jar" />
          </fileset>
        </classpath>
        <arg value="@{in}"/>
        <arg value="@{out}"/>
      </java>
    </sequential>
  </macrodef>
XSD ができれば JAXB を使用して Java XML バインディングを行います。これで OpenFeint API の XML を気にすることなくコーディング出来ます。 JAXB で XML Binding を行う ant のマクロ定義例

  <macrodef name="xsd2jaxb" description="works fine">
    <attribute name="package" />
    <attribute name="url" />
    <attribute name="dir" />
    <sequential>
      <delete>
    	<fileset dir="@{dir}">
    	  <include name="*.java" />
    	</fileset>
      </delete>
      <exec executable="${xjc.bin}">
        <arg line="-p @{package}"/>
        <arg line="-d @{dir}"/>
        <arg line="@{url}"/>
      </exec>
    </sequential>
  </macrodef>
OAuth API をラップしたコードと自動生成された XML Binding コードを使用して OpenFeint API for GAE/J を作成していきます。


完成したところで、外部 API であるハイスコアリストを呼び出してみます。
OpenFeint Ranking on GAE/J


まとめ

ハイスコア管理を外部 API として GAE 越えで OpenFeint API にアクセスするソーシャルアプリがこれで完成しました。通信が二段階で行われるため実用スピードにするにはもう少し工夫する必要がありますね。 OpenFeint API は GAE/J に移植できたわけですから Android にも簡単に移植できますね。これで iPhone, Android, Mixi 共通でハイスコア管理できたりできるようになりますよ。 もう一つ、XML のインスタンスから XSD を作成する方法は、●天 WEB SERVICE をはじめ国内の XML を返すウェブサービスがほとんど XSD なり DTD を公開していないためよく活用させてもらっています。

シリーズのまとめ

三回にわたりソーシャルアプリをお手軽に作成する方法を紹介しました。アプリ、ホスティング、ソーシャル API すべて無料で作成することができます。そして将来的に Mixi 等で公開してトラフィックが増えたとしても僅かな課金で行えそうだと言うレポートも存在します。みなさんもチャレンジしてみてはいかがでしょうか? OpenFeint for Java も独立したプロジェクトとして公開したいと思います。API が膨大なため実装が大変です。協力してくれる人いないかな?OpenFeint for Android を本家より先に出せたらなぁ?と妄想中です。