jQuery MobileによるPhoneGapアプリの構築

PhoneGap とは、Web技術でネイティブアプリケーションを作るためのHTML5プラットフォームです。つくられたアプリケーションはApp Storeに登録することも出来ます。アプリケーションは通常のHTMLページとして構築され、UIWebView や WebView (クローム無しのブラウザ、以後ウェブビューと呼ぶ) でネイティブアプリとして実行されます。この PhoneGap と jQuery Mobile を、組み合わせて使われることがよくあります。その際に有用やヒントや、はじめて開発する際にお勧めの情報などをまとめます。

アプリケーションの最初のドキュメントは、PhoneGapによって file:// URLを用いてローカルファイルとして読み込まれます。これはつまり、このページに会社のリモートサーバからページを取り込みたいような場合、絶対URLを指定する必要があることを意味します。なぜなら、アプリ上のドキュメントは file:// で始まるURLであり、ロードされるページや部品はクロスドメインのリクエストによりリモートサーバから取得されることになるからです。そしてそれは、一般的にはブロックされてしまいます。

PhoneGapとjQuery Mobileを使ったアプリケーションからクロスドメインページへアクセスするには、2つの鍵となるポイントがあります: $.suport.cors$.mobile.allowCrossDomainPages 、そしてPhoneGapで後にビルドされるホワイトリスト機能もまた、影響を与えます。

$.support.cors

jQueryコアには $.support.cors というブール型の設定を持っています。これは、ブラウザがW3Cの “Cross-Origin Resource Sharing” によるクロスドメインリクエストの機能をサポートしているかどうかを示すものです。

jQuery MobileはjQueryコアの $.ajax() 関数によりAjax通信を行います。ここで $.support.corstrue であれば $.ajax はクロスドメインページの読み込みが可能です。BlackBerryなど幾つかのプラットフォームでは、ウェブビューがクロスドメインでの読み込みをサポートしているにもかかわらずjQueryコアが誤って $.support.cors の値を false に設定してしまい、そのことが $.ajax() によるページの読み込み失敗の原因になっているという報告もあります。

$.mobile.allowCrossDomainPages

jQuery Mobileが外部ページを読み込もうとした時、リクエストは $.mobile.loadPage() を通じて送られます。これは $.mobile.allowCrossDomainPages の設定値が true の場合のみ許可されます。なぜなら、jQuery Mobileフレームワークは閲覧中のページを示すためにロケーションハッシュを使っています。そのことがクロスサイトスクリプティング(XSS)攻撃を可能にさせてしまい、クロスドメインURLでの読み込みを指定させてしまいかねないからです。そのため、デフォルトの $.mobile.allowCrossDomainPages の設定は false になっています。

このように、PhoneGapアプリでリモートサーバの “phone home” から読み込むためには $.support.cors$.mobile.allowCrossDomainPages の両方が true になっていなければなりません。この時 $.mobile.allowCrossDomainPages はクロスドメインリクエストが行われる前に設定されていなければならないので、これを mobileinit ハンドラで記述してやることをお勧めします。

$( document ).bind( "mobileinit", function() {
        // jQuery Mobile フレームワークの設定変更は、ここで行なってください!
        $.mobile.allowCrossDomainPages = true;
});

PhoneGapホワイトリスト

PhoneGap 1.0 で、クロスドメインリクエスト許可するサーバを列挙したホワイトリストの考え方が示されました。詳しくは PhoneGap wiki で見ることができます。

しかしながら、全てのプラットフォームでこのホワイトリスト機能が利用できるわけではありません。詳しくは PhoneGap のドキュメントで確認してください。PhoneGap 1.0 より古いバージョンでは、どんなサーバに対してもクロスドメインリクエストが通るようになっています。

その他

この他にも、PhoneGapに限った話ではないものの、ここで知っておくと良い幾つかのヒントを挙げておきます。

インストールアプリでは pushState機能 を無効にする この機能は、時にナビゲーションの挙動をおかしくします。そして、いずれにしろウェブビュー上ではURLが表示されないためプラスの効果はありません。これをアクティブにしておくべき理由は無いでしょう。

Androidのウェブビューで、URL読み込みのタイムアウト設定を変える 初期設定値は、おそらく必要以上に短いでしょう。この設定は、Android用のEclipseプラグインによりつくられるJavaクラスで変更できます。

super.setIntegerProperty("loadUrlTimeoutValue", 60000);