リポジトリ
以下のリポジトリで、記事中に含まれるコードを確認できる。
記事を読むことできるようになること
- ElixirDesktopでAndroid/iOSの機能を呼び出せる
省略する内容
- ElixirDesktopの初期化手順
- evaluateJavaScriptについて
本題
WebViewにはAndroidやiOSの機能を呼び出す機能がある。
具体的には、KotlinやSwiftのコードをWebView上から次の仕組みを用いて呼び出すことができる。
- Android:
Javacscriptinterface
- iOS:
WKWebView
,WKScriptMessageHandler
Android
AndroidではJavascriptInterfaceを使用する。
以下の手順で作業を行う
- JavascriptInterfaceを有効化
- 関数定義
- JavaScriptからの呼び出し
JavascriptInterfaceを有効化
Bridge
クラスのinit
に以下の記述を追加し、JavascriptInterfaceを有効にする。
init {
// 略
webview.addJavascriptInterface(this, "Android")
}
関数定義
@JavascriptInterface
を付与して、JSから呼び出す関数を定義する
@JavascriptInterface
fun sample1(): String? {
return Build.VERSION.RELEASE
}
JavaScriptからの呼び出し
以上の記述を追加することで、JSから以下の記述でAndroidの機能や関数を呼び出すことが可能である。
以下の記述により定義したsample1
関数を呼び出せる
webview.Android.sample1()
IOS
iOSでは、メッセージハンドラを使用してJavascriptから関数を呼び出す。
値を返却する場合はevaluteJavascript
を用いる必要がある。
以下の手順で作業を行う
-
override init()
内にメッセージハンドラを登録する -
userContentController
に、メッセージに対応する処理を記述する - 必要に応じて
evaluteJavaScript
で値を返却する
メッセージハンドラの登録
WebView.swift内のoverride init()
でメッセージハンドラを登録する。
override init() {
// 略
configuration.userContentController.add(self, name: "sample1")
}
メッセージに対応する処理
メッセージハンドラに対応する処理を`userContentController{関数内に記述する
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
switch message.name {
case "sample1":
let osVersion = UIDevice.current.systemVersion
self.evalJavaScript(message: osVersion)
// 略
}
}
値の返却
値を返却する場合は、evaluateJavaScript関数を使用してJavaScriptの関数を呼び出す。
func evalJavaScript(message: String) {
let executeScript: String = "window.callFromNative(\"\(message)\");"
webview.evaluateJavaScript(executeScript, completionHandler: {(object, error) -> Void in
if let object {
print(object)
}
if let error = error {
print(error)
}
})
}
呼び出し
JavaScriptからは以下のように呼び出すことが可能である。
window.webkit.messageHandlers.sample1.postMessage("sample1");
const sample1 = (message) => {
document.getElementById("ios-ver").textContent = message;
}
window.callFromNative = sample1;
ちなみにpostMessage
に渡している引数は、特に使用しなければなんでもよい。
まとめ
Androidの手順
-
init {}
にwebview.addJavascriptInterface(this, "Android")
を追記する -
@JavascriptInterface
を付与した関数を定義する - JavaScriptから
window.Android.関数()
で呼び出す
iOSの手順
-
override init()
にconfiguration.userContentController.add(self, name: メッセージ名)
を追記する -
userContentController
関数に、メッセージに対応する処理を記述する - JavaScriptから
window.webkit.messageHandlers.メッセージ.postMessage(引数);
で呼び出す - 値を返却する場合、
webview.evaluateJavaScript
を使用する - JavaScriptで対応する関数を定義する
特に(1)の記述漏れに注意すること