2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ElixirDesktop: WebViewからAndroidとiOSの機能を呼び出し

Last updated at Posted at 2024-12-19

リポジトリ

以下のリポジトリで、記事中に含まれるコードを確認できる。

記事を読むことできるようになること

  • 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を有効にする。

Bridge.kt
init {
    // 略
    webview.addJavascriptInterface(this, "Android")
}

関数定義

@JavascriptInterfaceを付与して、JSから呼び出す関数を定義する

Bridge.kt
    @JavascriptInterface
    fun sample1(): String? {
        return Build.VERSION.RELEASE
    }

JavaScriptからの呼び出し

以上の記述を追加することで、JSから以下の記述でAndroidの機能や関数を呼び出すことが可能である。

以下の記述により定義したsample1関数を呼び出せる

webview.Android.sample1()

IOS

iOSでは、メッセージハンドラを使用してJavascriptから関数を呼び出す。
値を返却する場合はevaluteJavascriptを用いる必要がある。

以下の手順で作業を行う

  1. override init()内にメッセージハンドラを登録する
  2. userContentControllerに、メッセージに対応する処理を記述する
  3. 必要に応じてevaluteJavaScriptで値を返却する

メッセージハンドラの登録

WebView.swift内のoverride init()でメッセージハンドラを登録する。

WebView.swift
override init() {
    // 略
    configuration.userContentController.add(self, name: "sample1")
}

メッセージに対応する処理

メッセージハンドラに対応する処理を`userContentController{関数内に記述する

WebView
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の手順

  1. init {}webview.addJavascriptInterface(this, "Android")を追記する
  2. @JavascriptInterfaceを付与した関数を定義する
  3. JavaScriptからwindow.Android.関数()で呼び出す

iOSの手順

  1. override init()configuration.userContentController.add(self, name: メッセージ名)を追記する
  2. userContentController関数に、メッセージに対応する処理を記述する
  3. JavaScriptからwindow.webkit.messageHandlers.メッセージ.postMessage(引数);で呼び出す
  4. 値を返却する場合、webview.evaluateJavaScriptを使用する
  5. JavaScriptで対応する関数を定義する

特に(1)の記述漏れに注意すること

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?