WKWebViewとJavaScriptを連携すると、いろいろな処理が実現できます。
アプリはSwiftとSwiftUI、サーバはHTMLとCSS(JavaScript)でコードを書いてみました。

適当な文字列を入力するとXcodeのログに出力されます。

今回は以下の手順でテキストボックスの入力情報を取得します。
- WebViewでJavaScriptを挿入
- ユーザがWebページのテキストボックスに入力
- 入力と同時にJSからアプリへ入力値を送信する
WebViewとJSのコードをそれぞれ解説していきます。
Webページ
テキストボックスを2つ設置したシンプルなWebサイトを作ります。
<form action="" method="get">
<div>
<label for="email">Enter your email: </label>
<input type="email" name="email" id="email" required />
</div>
<div>
<label for="pass">Enter your password: </label>
<input type="password" name="password" id="pass" required />
</div>
<div>
<input type="submit" value="Sign in" />
</div>
</form>
<p class="log"></p>
<p class="log2"></p>
<p class="log3">This is Sample.</p>
アプリ(WKWebView)
SwiftUIでWKWebViewを使えるようにします。
struct WebViewContainer: UIViewRepresentable { ... }
Coordinatorで各種Delegateを使えるようにします。
class Coordinator: NSObject, WKUIDelegate, WKNavigationDelegate, WKScriptMessageHandler { ... }
以下の関数はページの読み込みが終わったタイミングで呼ばれます。
// JSを実行する
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
webView.evaluateJavaScript("ここに実行するJSを記載します。")
webView.configuration.userContentController.add(self, name: "changeTextbox")
}
// JSからのデータを受け取る
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if(message.name == "changeTextbox"){
let param = message.body as! String
print(param)
}
}
evaluateJavaScriptで、JSを実行することができます。
実行するJSは文字列で指定します。(文字列で記載すると見づらいので別途JSとして記載)
ちなみに、evaluateJavaScriptはcompletionHandlerを使って実行結果を受け取ることもできます。
changeTextboxという名前の関数を登録しておき、データをuserContentContollerのdidReceiveで受け取ります。
evaluateJavaScriptで実行するJSは以下の通り。
// input要素のidを指定する
const email = document.querySelector('#email');
// 出力用のp要素のclass名と関数名をオブジェクトにして渡す。
email.addEventListener('input', {outputname: '.log',handleEvent:handleChange});
const pass = document.querySelector('#pass');
pass.addEventListener('input', {outputname: '.log2',handleEvent:handleChange});
// inputの値が変わるたびに呼ばれる。
function handleChange(event){
const value = event.target.value;
document.querySelector(this.outputname).innerHTML = value;
webkit.messageHandlers.changeTextbox.postMessage(value)
}
changeTextbox.postMessageで入力データをアプリ側に送信します。
まとめ
シンプルなコードでWebViewでJSを実行してユーザのデータを取得することができました。
便利な反面、悪用されると怖いのでJSやWebViewの取り扱いには注意が必要です。