Titanium

iOSでTi.UI.WebView内のTi.APP.fireEventが実行できる仕組み

More than 5 years have passed since last update.

Titaniumのネイティブ側とWebViewのHTML内のJavascriptでメソッドの実行やデータを橋渡しする仕組みとしては、evalJS()とTi.App.fireEvent/Ti.App.addEventListenerの二通りがあります。

iOSではもともとevalJSにあたる機能は用意されていますがWebViewからネイティブ側を呼び出せるようにはなっていません。ではどうやって実装されているのでしょうか?。

WebViewでHTMLをロードした際にTitaniumは こちらのJavascriptを追加します。

このうち、HTML側で呼び出されたTi.App.xxxやTi.API.xxxは


webview.js

Ti.App.fireEvent = function (name, evt) {

Ti._broker('App', 'fireEvent', {
name: name,
event: evt
})
};

のようにTi._broker(module, method, data)を呼び出します。

次にTi._broker()では「app://〜」で始まるURLにidやデータをシリアライズしたパラメータを追加したXMLHttpRequestを発行します。


webview.js

Ti.App._xhr = XMLHttpRequest;

Ti._broker = function (module, method, data) {
try {
var url = 'app://' + Ti.appId + '/_TiA0_' + Ti.pageToken + '/' + module + '/' + method + '?' + Ti.App._JSON(data, 1);
var xhr = new Ti.App._xhr();
xhr.open('GET', url, false);
xhr.send()
} catch (X) {}
};

「え、もしかしてTitaniumは内部にサーバーを起動させていて、、、?」いやそんなことはなく、単にネイティブ側はWebViewから呼び出されるURLの宛先を監視していて、そのうちapp://〜についてパラメータを解析することで実行するTitanium側のメソッドや引数を決定しているようです。

逆にネイティブ側からHTML側のTi.App.addEventListener (name, callback)でイベントを受け取る仕組みは、


webview.js

Ti.App._listeners = {};

Ti.App._listener_id = 1;

//(略)

Ti.App.addEventListener = function (name, fn) {
var listeners = Ti.App._listeners[name];
if (typeof (listeners) == 'undefined') {
listeners = [];
Ti.App._listeners[name] = listeners
}
var newid = Ti.pageToken + Ti.App._listener_id++;
listeners.push({
callback: fn,
id: newid
});
Ti._broker('App', 'addEventListener', {
name: name,
id: newid
})
};


で受け取るイベントをlisteners配列を登録しておきます。

そしてネイティブ側は登録されたlistenersに対するイベントがfireされるとTi.App._dispatchEvent(type, evtid, evt)を呼び出します。


webview.js

Ti.App._dispatchEvent = function (type, evtid, evt) {

var listeners = Ti.App._listeners[type];
if (listeners) {
for (var c = 0; c < listeners.length; c++) {
var entry = listeners[c];
if (entry.id == evtid) {
entry.callback.call(entry.callback, evt)
}
}
}
};

こうしてネイティブとHTML内でメソッドやデータを受け渡しが他のグローバルイベントと同じ書き方で手軽に利用できる点はTitaniumのCoolな部分ではないでしょうか。