iOSアプリで任意のJavaScriptをWebビューに注入しWeb側で実行する方法
chocoZAP iOSアプリ開発を担当している田中です。
アプリ側で固有に保持する値をWebに受け渡す際に、クエリパラメータやCookieを経由するなどいくつかの方法が考えられますが、今回はアプリ側で定義したJavaScript関数をWKWebに注入するという手法を用いたので、その実装方法をご紹介します。
WKUserScriptでスクリプトを定義する
Apple のドキュメントに以下の概要が記されており、まさに今回の要件を満たしてくれそうです。
WKUserContentControllerにスクリプトを追加する
ここで生成したスクリプトは、 WKWebConfiguration の持つ userContentController に対して追加することでWeb側から実行できます。
追加が可能なタイミングはWKWebConfiguration の初期化時に限らず任意のタイミングで行えます。たとえば WKNavigationDelegate.web(_:didStartProvisionalNavigation:) などでURLの変更を補足して動的に注入することも可能でした。
WKUserScriptは生成時にその注入タイミング injectionTimeをコンテンツのローディング状態に応じて指定することが可能です。Web側でのスクリプト実行タイミングに対して適切な指定をしましょう。
実装例
// ① Web側で実行したい関数を定義する
let codeText = """
function getSomeID()
{
/* 例:アプリで保持する値をWeb側に連携する */
return "\(someIDValue)"
}
"""
// ② WKWeb にスクリプトを追加する
let script = WKUserScript(source: codeText, injectionTime: .atDocumentStart, forMainFrameOnly: true) web.configuration.userContentController.addUserScript(script)
Web側では、すでにJavaScriptに注入された関数を呼び出すだけです。
result = getSomeID();
console.log(result);
おわりに
こうしたWebからアプリ側の処理を呼び出す機会は、個人的にあまり多くなく知見が乏しかったため、勉強になりました。