近頃話題の Titanium Mobile でラクラク iOS アプリ開発してみた このエントリをはてなブックマークに登録

2010年12月28日

もりもりもりもり / , , , , ,

最近 FF11 が楽しくて仕方がないもりやまです。
日頃から FINAL FANTASY XI WikieLeMeN – FF11 等を参考にしているのですが、そんな中に FF11用語辞典 ~ ウィンダスの仲間たち版があります。
移動中に iPhone で眺めることが時々あるのですが、PC 用のビューそのままなので拡大しないと読めなくて使いにくいなぁと思っていました。
そこで、最近各所で話題の Titanium Mobile を使って、iPhone で読みやすくするためのアプリを作ってみることにしました。

Titanium Mobile

Titanium Mobile とは、JavaScript を使って iOS / Android のネイティブアプリを開発するためのミドルウェアです。BlackBerry にも対応予定のようです。

titanium-mobile-doc-jaプロジェクトにとてもよくできた日本語ドキュメントがあるので、こちらで紹介するまでもないのですが、いくつか特徴を挙げると、

  • ネイティブのUIコントロールが使える
  • メモリ管理を意識する必要がない
  • 記述量が Objective-C に比べて少ない
  • HTMLからは使えない機能にもアクセスできる

といったようなものがあります。

詳しくはAppcelerator Titanium MobileでiPhoneアプリ開発を始めよう!!を読んでみてください。

他にもたくさん紹介記事は上がってきているので、今回は実際にアプリを作ってみた時の試行錯誤した部分等を中心に書いていこうと思います。

実機にはどうやってインストールするの?

インストールしてシミュレータで動かすまでは簡単だったのですが、実機でのテストに必要な設定で少し躓きました。

「Test & Package」>「Run on Device」を選択すると、初期状態では以下のような状態で表示されると思います。

  1. Sign-up for iPhone Develper Program
  2. Register your iPhone with Apple
  3. Obtain WWDR Intermediate Certificate from Apple
  4. Obtain Development Certificate from Apple
  5. Obtain Development Provisioning Profile from Apple
  6. Upload Development Provisioning Profile

1 については言うまでもないですね。
2〜5 は iOS Provisioning Portal での作業になります。
iOS SDK での開発ができる環境であれば、この辺りの作業は全て完了していると思います。

3 と 4 の証明書がキーチェーンに追加されている状態だと、以下のような状態になります。

Titanium Developer が起動した状態で証明書をインストールした場合、一度 Titanium Developer を再起動しないと認識されないので注意が必要です。

5 のプロビジョニングプロファイルだけは、既にインストールされていても認識してくれないようです。
*.mobileprovision ファイルが手元に無い場合は iOS Provisioning Portal から再度ダウンロードして、6 の「Upload Development Provisioning Profile」の「Upload」をクリックして、*.mobileprovision ファイルを選択します。
iPhone 構成ユーティリティが入っていればそちらが、無ければ Xcode のオーガナイザが開いて、プロファイルがインストールされます。インストール済みの場合は上書きの確認が出るので、問題無ければ上書きしてしまいます。
どこに「Upload」するのか不安だったのですが、どこにもアップロードはしないようです。

最終的には以下のような状態になると思います。

これで実機テストまでできる環境が整いました。

WebView が操作できない!

今回作ったアプリケーションは、PC 版のサイトから必要な部分だけをスクレイピングして WebView に表示する部分がキモになりました。
当然 WebView なので、表示しているコンテンツに含まれるリンクをタップしたらページ遷移してしまいます。
そこでリンクのタップをフックして、アプリケーション側で制御できるように、表示している WebView に addEventListener でイベントハンドラを登録したのですが、タップを拾うどころか操作を一切受け付けなくなってしまいました
調べてみたところ、こちらの記事で解決方法が紹介されていたのですが、試してみたところこれだけでは解決しませんでした。
ページが表示される前に表示に必要な部分だけをスクレイピングしたかったので、load イベントもフックしていたのですが、こちらも影響するようです。
よくよく WebView の API リファレンスを読んでみると、ページの一番最後に

Since a webview internally wants to handle its own events, scrolling and other related touch events against it’s own view surface, you cannot have both Titanium style events against the webview instance and internal Javascript events in the DOM. You must choose between one or the other.
(意訳)WebView 自身が内部でスクロール等のイベントをハンドリングする必要があるので、WebView インスタンスに対する Titanium スタイルのイベントと、DOM 内の JavaScript イベントを同時に扱うことはできません。

というようなことが書かれていました。
WebView.addEventListener はおそらく前者だと思うのですが、後者を使っていた意識はありませんでした。
ちょっとよく分かっていないのですが、以下のようなフローにすることで解決しました。

// 1. Titanium.App に独自のタップイベントを受け取るイベントリスナを登録
Ti.App.addEventListener(context + 'LinkClick', function(event) {
  var data = event.url.match(/\/?(\d+)\.html$/);
  var browser = new Browser(data[1]);
});

var Browser = function(id) {
...
  // 2. 通信用の WebView(以下 proxy)を作成
  this.proxy = Ti.UI.createWebView({url: 'http://wiki.ffo.jp/html/' + id + '.html'});
  // 3. proxy に load イベントを受け取るイベントリスナを登録
  this.proxy.addEventListener('load', $.proxy(this._proxyOnLoad, this));
  // 4. proxy の URL をロード
  this.proxy.reload();
...
};

Browser.prototype = {
  _proxyOnLoad: function(event) {
...
    // 5. ロード完了で 3 で登録したイベントリスナが起動するので、proxy の html の <a> タグを書き換えて、onclick に 1 で登録したイベントを起動する処理を設定
    this.proxy.evalJS('$.each($("#content .content a[href]"), function(i,v){ $(v).attr({"onClick": "return clickHook(this, \'' + context + '\');"}); });');
    // 6. 表示用の WebView(以下 browser)を作成して、html プロパティに proxy の html から必要な部分だけをスクレイピングして設定
    var browserView = Ti.UI.createWebView({html: template.replace(/<body><\/body>/, '<body>' + this.proxy.evalJS('$("#content .content").html();') + '</body>')});
    // 7. browser を window.add して表示
    this.window.add(browserView);
...
  }
};

これでようやく期待通りの動作をするようになりました。
WebView を 2 つ使うことになってしまったのでリソース的にはよろしくないですが、HTML のスクレイピングがこんなに簡単にできることのトレードオフということで。。。

コードだけで UI 作るのしんどい。。。

Titanium Mobile では、UI の作成はすべて JavaScript のコードで行う必要があります。
2011 年第2四半期には Titanium Designer という UI デザイン用のツールがリリース予定のようですが、現状そういったものは公式にはありません。
しかし、Interface Builder で作成した XIB ファイルを Titanium Mobile 用の JavaScript のコードに変換してくれる「Xib2Js」というツールがこちらでリリースされています。
今回 TableView のレイアウトをこれでやってみました。
作成するのは以下のような UITableViewCell です。


UITableViewCellStyleSubtitle と同じレイアウトなのですが、Titanium.TableViewRow には設定できそうなプロパティが見当たらなかったので、自力で作ることにしました。

Xib2Js を起動すると、以下のようなシンプルなウィンドウが開きます。

ここにさっきの UITableViewCell の XIB ファイルをドロップすると、、、

JavaScript のコードに変換されました!
すべての設定が変換されているわけではないので、足りない分は自分で追加する必要がありますが、ひな形としては十分です。

作ったアプリ

こんな感じのができました!

/sh 助けて!

アプリはできたんですけどアイコンやスプラッシュ画像がありません。誰か書いてくれませんか?
アイコンやスプラッシュ画像が用意できたら AppStore に申請しようと思っていますが、ソースコードは公開していますので、先に使いたいという方は GitHub からダウンロードしてビルドしてみてください。
https://github.com/morimori/ffxi_glossary_browser

参考にしたサイト

クレイについてもっと知りたい方は…

  1. クレイの3つの強みを見てみる。
  2. WEBシステムのことなら何でもご相談ください。

「いいね!」で応援よろしくお願いします!

このエントリーに対するコメント

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


トラックバック
  1. Titanium Mobileで画像の複数選択モジュールを作ってみた | KRAY Inc2011/07/06, 11:55 AM

    […] クレイでは森山がブログを書いていたり、ダニーが仕事で使っていたりと多少実績はあるのですが、私自身は全くさわったことがありません。必要に迫られて、いきなりモジュール開発 […]

we use!!Ruby on RailsAmazon Web Services

このページの先頭へ