Titaniumが楽しすぎてやばい

id:naoya さんの記事で気づいた Titanium ですがあまりに楽しいのでここ1週間ほど暇があればコードを書いています。そろそろ、プロダクトレベルのモノが仕上がりそうなので AppStore に提出したいところ。

ただし、iPhoneとAndoridアプリが一気に作れる、とか思ってさわると結構機種依存のコードを書く必要に迫られるので期待を裏切られます。ロジックのコードが共通化できるぐらいに考えていたほうが気楽だと思います。それでも、Cで書いてiPhone,Androidで共通化するよりはよっぽどらくだと思いますが。

最近は iPhone で動くことだけを考えて、実装しているので、今回は

  • Objective-C で実装している時との比較
  • はまりどころ
  • PhoneGap との違い

をメモしておきます。

Objective-Cと比べて良い

メモリ管理不要

もうこれだけで、僕は移行したくなります。デストラクタも書かなくてよいし。
逆にいえば、細かいメモリの管理は難しいかもしれないですね。計測してないですが。
ちなみに計測するときは、Titanium で作った Project に Xcode プロジェクトがあるので、そいつをコンパイルして、Instruments と一緒に起動すればメモリ使用量なども計測できます。

call backが簡単

iOS SDK 4 でブロックが渡せるメソッドが出てきたとは言え、

imageView.addEventListener('load',fucntion(e){Ti.API.debug('image loaded');});

とか1行で書けるわけないですし。

開発サイクルがwebっぽい

とりあえず、書いて試して、の繰り返しがかなり早くできます。これは書き換えてから起動までが、かなり高速だからかと思います。

コードが短い

短くてすむということは、Objective-Cの用にに、ファイルも、クラスもたくさん作ってみたいなことが要らないわけで管理や見通しが楽になります。大体1ビュー1ファイルでも酷いことにはならないと思います。ModelとControllerを厳密に分ける必要性を感じない。

作っていて楽しい

Objective-Cが楽しくないわけじゃないのだけれども、あまりにサクサク作れるので不思議な高揚感が湧いてくる感じ。

Objective-Cと比べて悪い

ゲームとか、低レベルAPI叩くようなアプリを作成しないならあまり悪い点が思いつかない。しいてあげるなら、あるいは業務で使うならいかが問題かと思います。

使える外部ライブラリは減る。というより無くなる。

自分でラッパーをかけば使そう。でもメジャーなものは、既に中で使われているので案外必要に迫られないです。ASIHTTPRequest とか GDataのXMLParser とか。

詰まった時に自分で直せるきがしない

ちょっと前のバージョンまで、けっこう致命的なバグが残ってたみたいで、TitaniumのQ&Aを読んでると、バージョンあげると直ると書いてあることは多いです。かといってTitaniumの不具合を自分でパッチ書いて治すというのはちょっと大変かも。そういうバグに当たった時にどう対処するかが非常に問題になりそうです。

はまりポイント

バージョンアップも結構早いし、日本語ドキュメントは少ないしとハマるところは結構あります。

APIドキュメントよりKitchinSinkを見たほうが良い

当たり前といえば当たり前なのですが、開発ブランチの1.4.2や1.5.0などでは、WebにあるAPIドキュメントには書いてあるのメソッドやオブジェクトがなくなってることがあります。デモアプリのKitchinSinkの最新版は、Titaniumの最新版で動くようになっているので、こちらを見たほうが正確です。やりたいことが決まったら、KitchinSinkに近い実装がないか探す、コードを読む。という手順が良いと思います。

xhrでhtmlをとってきて DOM を作りたい。

ここから先は、自分がはまった細かい実装ポイント。
Titanium には document ノードが無いので、 HTML から DOMを簡単につくれません。

var xhr = Ti.Network.HTTPClient();
xhr.onload = function(){var xml = this.responseXML};

とやれば xml のパースはできますが、htmlだとエラーです。(parserはGDataの
XMLParserだし。)

速度を気にしないなら、YQLを使うほうが楽です

Ti.Yahoo.yql(
"select * from html where url = 'http://b.hatena.ne.jp/' and xpath=\"//link[@type='application/rss+xml']\"",
function(e){Ti.API.debug(e insetanceof 'Array' ? e.link[0].href : e.link.href )}
)

みたいな感じで、サイトの rss がどこにあるか取れたりします。

画像をwebから取得したけどサイズがわからない
var window = Ti.UI.createWindow();
var imageView = Ti.UI.createImageView({
    image:'http://htn.to/motemen',
    width:320
});
window.add(imageView);
window.open;

で良しなに、画像を撮ってきて表示してくれるはずなのですが、これだとアスペクトがおかしくなります。ローカルにある画像なら大丈夫なのですが、リモートの画像だとうまくいきません。そんな時は、onloadイベントで、

imageViwe.onload(e){Ti.API.debug(imageView.toImage().width)};

とかやると、リモート画像の元の解像度が取れるので、そこから調整してやるといいと思います。ちなみにtoImageをonloadよる前によぶと表示領域にリサイズした画像が取れたりするので注意が必要です!

もっと書きたいこともあるし、すごい興奮してるのですが明日も早いので寝よう!!
だれか雑誌連載させて!と思うぐらい楽しい!