無料Wikiサービス | デモページ
Linuxなどのメモ書き

PhoneGap: NativeCodeの呼び出し


PhoneGap(iPhone)を使うと、JavaScriptからGPSなどアプリ用のデバイス機能にもアクセスできるのだが、どのような仕組みになっているのか不思議だったので調査した。

JavaScript -> Native(Objective-C) Codeの呼び出し

GPSの機能などを使う場合、JavaScriptからObjective-Cで書かれたプラグインを呼び出す。
Objective-Cのコードを呼び出すには、PhoneGapLib/javascripts/core/phonegap.js.baseのPhoneGap.exec()を使う。

PhoneGap.exec()はコマンドをキューに入れるだけで、キュー内のコマンドの実行はPhoneGap.run_command()で行う。

PhoneGap.run_command()はダミーのiframeを作成して、

gap://<Class>.<command>/[<arguments>][?<dictionary>]

のような形式のURLを作成してRequestを発行する。

Requestが発行されると、Objective-Cのコードが動き出す。UIWebViewDelegateにwebView:shouldStartLoadWithRequest:navigationType:
というメソッドがあり、これは、webViewがコンテンツの読み込みを開始する前に呼び出される。これを使って、gap://へのアクセスを捕まえている。PhoneGapの場合、PhoneGapLib/Classes/PhoneGapDelegate.mの PhoneGapDelegateクラスのwebView:shouldStartLoadWithRequest:navigationType:メソッドが呼び出される。

webView:shouldStartLoadWithRequest:navigationType:メソッドは、ReuqestのURLがgap://だった場合は、URLからメソッド名や引数を抽出し、プラグインのメソッドを呼び出す。

例として、位置情報を扱うPhoneGap用のJavaScriptコードPhoneGapLib/javascripts/core/geolocation.jsでは、以下のようにしてNativeCodeを呼び出している。

JavaScript側:
PhoneGap.exec("Location.startLocation", args);  // gap://xxxへRequest発行

Objective-C側:
webView:shouldStartLoadWithRequest:navigationType:  // メソッドが呼ばれる
gap://xxxxへのアクセスなら、URLからプラグインのメソッドと引数を抽出し呼び出し。

"Location.startLocation"に対応する
PGLocation.startLocation();
を呼び出し。この中で、位置情報取得処理が行われる。

以上のようにして、JavaScriptコードからObjective-Cで書かれたコードを呼び出し、NativeアプリからしかアクセスできなかったGPS機能などが使えるようになっている。

うまい実装のしかただ。

Objective-CからJavaScriptへデータを渡す

一方、呼び出されたObjective-CのコードからJavaScriptへ値を返す必要もある(取得した位置情報を返すなど)。これは、UIWebViewのstringByEvaluatingJavaScriptFromStringメソッドを使えば簡単に実現できる。stringByEvaluatingJavaScriptFromStringは引数の文字列で与えたJavaScriptコードを実行する。

位置情報関連のプラグインであるPhoneGapLib/Classes/Location.mでは以下のようにしてJavaScriptのgeolocation.setLocation()を呼び出して、JavaScript側に位置情報を返している。

NSString * jsCallBack = [NSString stringWithFormat:@"navigator.geolocation.setLocation({ timestamp: %.00f, %@ });", epoch, coords];

[super writeJavascript:jsCallBack];

(writeJavaScriptメソッドはstringByEvaluatingJavaScriptFromStringを呼び出す)

Classes/Location.m locationManagerメソッド


最終更新 2011/07/17 18:39:26 - kztomita
(2011/07/17 18:15:43 作成)