[iOS] WKWebView と JavaScript を連携する

前提条件

以下の環境で実行しています。

  • Xcode 12.0
  • iPhoneシミュレータ: iOS14系

Qiita: iOS WKWebView ネイティブとローカルJavascript連携 を参考に、それに更に調査を加えました。

JavaScript から WKWebView への連携

アプリ側のコード

まずWKWebViewConfiguration に WKUserContentController を設定し、それをWKWebView に食わせます。
適当なUIViewController 上のコードです。

let config = WKWebViewConfiguration()     
let userContentController: WKUserContentController = WKUserContentController()
userContentController.add(self, name: "hogehogeCallBack")
config.userContentController = userContentController
         
let webView = WKWebView(
    frame: CGRect(x: 0, y: 0, width: 100, height: 100),
    configuration: config
) 
view.addSubview(webView) 

userContentController.add(self, name: "hogehogeCallBack") で、どこが何のコールバックを受けるのか設定しています。

self の箇所は、どのクラスがコールバックを受け取るかを示します。
この場合は self なので、自分自身のクラスが受け取ります。
hogehogeCallBack は、何のコールバックを受け取るかを示します。
この場合は JavaScript から hogehogeCallBack という名前で受け取ります。

次にコールバックを受け取ったあとの処理を書きます(何となくextension で分けています)。

extension SampleViewController: WKScriptMessageHandler {
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
        if(message.name == "hogehogeCallBack") {
             print("🐱: \(message.body)") 
        }
    }
} 

とりあえずprint するだけですが、これでコールバックを受け取って処理することができます。

JavaScript 側のコード

これは一行です。

webkit.messageHandlers.hogehogeCallBack.postMessage("This is hogehogeCallBack"); 

これで、上記の WKScriptMessageHandler のデリゲートメソッドにて”🐱: This is hogehogeCallBack” という文字列が出力されます。

ちなみに、ここで渡しているのはString型ですが、他の型も渡すことができます。

色々な型の受け渡し

例えばArray型の受け渡し。
JavaScript 側のコード。

var array = [1, 2, "a"];
webkit.messageHandlers.hogehogeCallBack.postMessage(array);

アプリ側のコード。

        if(message.name == "hogehogeCallBack") {
            if let array = message.body as? [Any] {
                print("🐱: \(array)")
            }
        } 

上記の例だとJavaScript からは Int と String ごちゃ混ぜの配列を渡しているため、
受け取りのWKWebView 側では Any 型の配列として扱っています。
Int や String のみの配列の場合は、WKWebView 側でもその通りに扱えます。

次に、例えばDictionary 型の受け渡し。
JavaScript 側のコード。

var dictionary = {
    a: 1,
    b: 2,
    c: "a"
};
webkit.messageHandlers.hogehogeCallBack.postMessage(dictionary);

WKWebView 側のコード。

        if(message.name == "hogehogeCallBack") {
            if let dictionary = message.body as? [String: Any] {
                print("🐱: \(dictionary)")
            }
        } 

また、例は載せませんがJavaScript から小数点の数値が渡された場合も、WKWebView 側ではFloat や Double 型として受け取れます。

なのでプリミティブ型は基本受け取れそうです。
JSONで扱える型は、WKWebView 側で受け取れるということかもしれません🤔

次に、WKWebView から JavaScript への連携です!

WKWebView から JavaScript への連携

JavaScript 側のコード

適当に足し算した結果を返却する関数を定義してみました。

function add(a, b) {
    return a + b;
} 

アプリ側のコード

アプリ側では、以下のように evaluateJavaScript メソッドを呼びます。
completionHandler はJavaScript の返り値があるときに、この中で扱えます。

webView.evaluateJavaScript("add(1, 2);", completionHandler: { (object, error) -> Void in
    print("🐱: \(object)")
}) 

この場合は JavaScript の add 関数に、引数1と2を与えて実行しています。
結果はこのようにprint されます。

🐱: Optional(3)

HTMLのロードが終わってからでないとJavascriptのコードを実行できない点にご注意を (Qiita: iOS WKWebView ネイティブとローカルJavascript連携 より)

最後に

以上です。お疲れ様でした!

[iOS] WKWebView と JavaScript を連携する」への1件のフィードバック

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Google フォト

Google アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。