2011/08/15

Titanium mobile へのモジュールの読み込み

この記事の結論は、モジュールの読み込み指定には
<modules>
  <module platform="iphone" version="0.1">com.bar.foo</module>
  <module platform="android" version="0.1">com.bar.foo</module>
</modules>
というように、platform属性を書くべきだ、ということです。
これについては、AppceleratorのQ&Aの
Compile fails when having both an iPhone and Android module
で簡単に触れられているだけです。以下に状況も含めて説明します。


iOS用とAndroid用両方のモジュールを作っていると、おかしなエラーに遭遇することがあります。
例えば、module idを”com.bar.foo"とすると、Ti StudioでモジュールのテストアプリをiOS用にビルドすると、次のようなエラーになることがあります。
[DEBUG] Looking for Titanium Module id: com.bar.foo, version: 0.1, platform: <any platform>
[ERROR] Third-party module: com.bar.foo/0.1 missing library at /Library/Application Support/Titanium/modules/android/com.bar.foo/0.1/libcom.bar.foo.a
[ERROR] Error: Traceback (most recent call last):
 File "/Library/Application Support/Titanium/mobilesdk/osx/1.7.2/iphone/builder.py", line 638, in main
    sys.exit(1)
SystemExit: 1
なぜかandroid用のモジュールディレクトリを探しています。そして、当然のことながらそこにはiOS用のモジュールのライブラリファイル(*.a)が存在しないので、エラーとなってしまいます。よく見るとplatform: <any platform>を探そうとしているらしいのですが、どうしてanyであるにもかかわらず、androidで停止してしまうのか怪訝に思います。
このとき、xapp.xmlには
<modules> 
   <module version="0.1">com.bar.foo</module>

</modules>
と指定してあります。
モジュールの開発過程を振り返ってみると、iOS用のモジュールを作り、サンプル用のアプリとインターフェースの調整をして、一通りつじつまの合うようにして、一旦iOS用の開発を中断して、Android用のモジュールの開発に移りました。iOSと同じように一通り完成したので、もういちどiOS用の開発に戻ったときこれが起きました。かなり時間を使ってから、Android用のモジュールの存在に気がつきました。
そうなんです。問題を引き起こしたのは、今まさに作ったばかりのAndroid用のモジュールです。試しに、Android用モジュールをTitaniumディレクトリから削除してみると、
[DEBUG] Looking for Titanium Module id: com.bar.foo, version: 0.1, platform: <any platform>
[INFO] Detected third-party module:com.bar.foo/0.1
となって、うまくビルドできます。 この方法で、iOS用のアプリがビルドできるのですが、ターゲットを変えるたびに、いちいちTitaniumディレクトリの中をいじるのは何かと面倒です。
(iOS用にビルドしているのにandroid用のモジュールディレクトリを探しているのがそもそも間違いなので、iOS用のbuild.pyを修正する方法もあります。しかしこれも何かと面倒です)。
そこで、platform属性の登場です。
<module version="0.1">com.bar.foo</module>
は、any platformのモジュールを意味しています。これをプラットフォームごとに指定するために、 
<module platform="iphone" version="0.1">com.bar.foo</module>
<module platform="android" version="0.1">com.bar.foo</module>
のように、platform属性を指定して、それぞれのプラットフォームだけを探すように指定します。幾分冗長な感じがしますが、現状のTitaniumのビルドシステムでは、最も簡単で安全な方法です。
モジュール開発だけでなく、アプリケーションをビルドする場合の問題なので、iOS、Android両環境向けにアプリケーション開発する場合は、必ずplatform属性を使った方がいいでしょう。


PS
ところで、any platformなんて、いったいどうしてそんなものが必要なのかよくわからないのですが、Javascript Native Moduleと呼ばれるモジュールがany platform向けのモジュールなんじゃないかな、と思っていたんです。しかしそれについてiOS用しかドキュメントされていないし、Android用は作れないようです。iOS用も*.aファイルになってしまうので共通で使える訳ではないようです。どうしてany platformなんて考えになったんですかね?

(2011/09/25)
CodeStrongもおわって、若干落ち着いたのか、着々と(?)ドキュメントが整備されつつあるようです。モジュール関連でも、モジュール利用法の新しいドキュメントがでたようです。これからは、これが正しい情報です。
Using Titanium Modules




0 件のコメント:

コメントを投稿