目次
前提条件
以下の環境で実行しています。
- 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件のフィードバック