[Titanium勉強日記 4] モジュールを作ってみる

同一View内に2つTableView A,Bがあって、AからBにドラッグドロップする機能を書きたいんですが、現状のTiUITableViewだとセルをつかむ処理をフックできなさそうなので、モジュールを作ってみようと思います。

まずは空のモジュールを作ってみます。例によってiPhone用です。公式ドキュメントの通りにやればできるのですがハマりました。何処かにidはネームスペースと書いていたので、モジュールはid.nameの形式になると思い込んでいてハマりました。以下の例だとcom.taichinoがモジュール名です。firstmodに意味はありません。

このコマンドを打つと、モジュール用のxcodeprojが生成されます。このxcodeprojに変更を加えてビルドするとモジュールができる仕組みです。プロジェクトのディレクトリ構造は以下のようになっています。Classes以下に普通にObjective-Cのコードを追加していく感じですね。またexampleディレクトリの下にあるapp.jsを編集して作成したモジュールのテストを行います。

$ titanium create --platform=iphone --type=module --name=firstmod --id=com.taichino
$ tree -L 2
├── Classes
│   ├── ComTaichinoModule.h
│   ├── ComTaichinoModule.m
│   ├── ComTaichinoModuleAssets.h
│   └── ComTaichinoModuleAssets.m
├── ComTaichino_Prefix.pch
├── LICENSE
├── README
├── assets
│   └── README
├── build.py
├── documentation
│   └── index.md
├── example
│   └── app.js
...
├── firstmod.xcodeproj
│   ├── project.pbxproj
│   ├── project.xcworkspace
│   └── xcuserdata
├── timodule.xml
└── titanium.xcconfig

ここではHello World的なモジュールを作ってみます。[File]->[New]->[File…]から、AppceleratorのTiProxyテンプレートを選択、ComTaichinoFooProxy.(h|m)を追加して、以下のように編集します。js側から渡された文字列をログに吐くだけの何でもない処理ですね。

//
// ComTaichinoFooProxy.h
//
#import "TiProxy.h"

@interface ComTaichinoFooProxy : TiProxy
- (void)bar:(id)args;
@end


//
// ComTaichinoFooProxy.m
//
#import "ComTaichinoFooProxy.h"

@implementation ComTaichinoFooProxy

- (void)bar:(id)args {
	NSLog(@"%@", args);
}
@end

ここでもクラス名に注意が必要です。プロジェクト作成時に指定したidをUpperCamelにした文字列をプリフィックスに、Proxyをサフィックスに指定しなければなりません。この例だとComTaichino + Foo + Proxyという事になります。正しく名前を指定すると、プリフィックスとサフィックスを削除した名前を元にcreate〇〇というファクトリメソッドが自動的にjs側に公開されます。この例ではcreateFooになります。

以上でcom.taichinoモジュールにFooオブジェクトを追加した事になります。早速app.jsに以下のコードを追加して、動作確認を行ってみます。

// app.jsのwrite your module tests hereと書かれている周辺に以下を追加
var firstmod = require('com.taichino');
var foo = firstmod.createFoo();
foo.bar('passed by jscode');

app.jsにコードを追加したらモジュールのプロジェクトルートで以下のコマンドを打ちます。コンソールに”passed by jscode”と表示されれば成功です。

$ titanium run
...
[DEBUG] (
[DEBUG] "passed by jscode"
[DEBUG] )

テストの際にビルドが走って、プロジェクトルートにモジュールのパッケージファイルが生成されています。このファイルがモジュールの最終生成物で、これを/Library/Application\ Support/Titanium/に置いておくと、別のプロジェクトからロードできるようになります。

$ ls *.zip
com.test-iphone-0.1.zip
$ cp com.test-iphone-0.1.zip /Library/Application\ Support/Titanium/.

あらかじめモジュールをロードする側のプロジェクトのtiapp.xmlに使用するモジュール一覧を指定しておきましょう。

<modules>
  <module version="0.1">com.test</module>
</modules>

最後にもう一点ハマった点があります。それはモジュールの内容を更新した時は、必ずモジュールを使っている側のプロジェクトのcleanが必要だということです。コマンドラインでビルドしている場合はプロジェクト直下のbuildディレクトリを削除します。そうしないと何処かで古いモジュールがキャッシュされていて更新が反映されません。僕はこれで半日潰しました。

以上でモジュールを作る流れは大体把握できました。最後にハマった点をもう一度列挙しておきます。

ハマりポイント

  • titanium createコマンドを打つ際のidがモジュール名。nameは特に意味がない。
  • TiProxyのサブクラスの名前は(idのUpperCamel) + クラス名 + (Proxy)。
  • モジュールを作り直したら、ロードする側でcleanが必要。

Leave a Reply

Your email address will not be published. Required fields are marked *