2010年 11月 30日

Titanium Mobile (iPhone) で、アプリの WebView 内HTMLの特定スキームをハンドリングするテクニック

ローカルHTMLや、直接HTMLを書く場合、Titanium オブジェクトがHTML側から可視なので WebView 内部と外部のコミュニケーションは別段難しくない (fireEvent したら良い) のだけれど、リモートHTML (自分のウェブサービスと協調させたいときとか) の場合はそうはいかないので、別の方法が必要。

ということでカスタムスキームは使えないのか? と思ったのだけれど、それらしいAPIはない。こりゃカスタムスキームのハンドリングはできないな、と思いきや別の方法により可能であることがわかった。

前置きともかく以下のようにするとできる。ここではカスタムスキーム名を custom: としている。

var webview = Titanium.UI.createWebView();

// ローカルでもリモートでもどっちでも良い
webview.url = 'http://localhost:5000/sketch.html';
//webview.html = '<!DOCTYPE html><html><body>' +
//	'<p><a href="custom:foobar">custom scheme</a></p>' +
//'</body></html>';

webview.addEventListener('error', function (e) {
	// "Error Domain=WebKitErrorDomain Code=101 \"The URL can\U2019t be shown\" UserInfo=0x6872120 {NSErrorFailingURLKey=custom:foobar, NSErrorFailingURLStringKey=custom:foobar, NSLocalizedDescription=The URL can\U2019t be shown}"
	if (/NSErrorFailingURLKey=custom:(\S+), /.test(e.message)) {
		var data = RegExp.$1;
		alert(data);
	}
});

Titanium.UI.currentWindow.add(webview);

コードの通りですが、WebView はハンドリングできないエラーがあると error イベントを発火するので、それをキャッチして処理してやるだけです。なので存在しないスキームしかハンドリングできないです。iPhone だと遷移も発生しないので割といい感じです。

なんか根本的に解決する方法があれば良いのですが、あれば教えて頂けると嬉しいです。