🐈

iOSのWebViewのJSイベントをSwiftへパスする方法

2022/07/18に公開

iOSアプリのWebViewとSwiftの繋がりは、二つのパターンがあります

  • WebViewからイベントを発生させ、そしてSwift側通知します(WebView→Swift)
  • Swiftから何かしらの事件を受け、そしてWebViewに動きを命令します(Swift→WebView)

今回が紹介したいのは、一つ目の「WebView→Swift」です

WebViewのレイアウト

まずは簡単にWebView付きのアプリを作成しようと思います

import UIKit
import WebKit

class ViewController: UIViewController {
	var webView: WKWebView!

	override func loadView() {
		webView = WKWebView()
		view = webView
	}

	override func viewDidLoad() {
		super.viewDidLoad()

		let html = """
		<html>
		    <head>
			<meta name ="viewport" content="width=device-width, initial-scale=1">
		    </head>
		    <body>
			<h1>aloha</h1>
			<button>Push Me</buton>
		    </body>
		</html>
		"""

		webView.loadHTMLString(html, baseURL: nil)
	}

}

そして、画面のボタンをクリックすると、Swift側を動かしたいので
繋がりの準備を進めます

WKScriptMessageHandlerを導入

まずはProtocolを加えます

+class ViewController: UIViewController, WKScriptMessageHandler {
}

そして、ViewControllerの中に、メソッドを追加します

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {

}

Configurationを設定

そしてuserControllerを追加しようと思います
view = webViewは、viewDidLoad()に移動させたいので一旦削除します

override func loadView() {
	webView = WKWebView()
-	view = webView
}

そして、viewDidLoad()の編集を行います

override func viewDidLoad() {
	super.viewDidLoad()
	
	let html = """ 省略中... """
	
+	let configuration = WKWebViewConfiguration()
+       configuration.userContentController.add(self, name: "ToApp")
        
+       webView = WKWebView(frame: webView.frame, configuration: configuration)
        webView.loadHTMLString(html, baseURL: nil)
        
+       view = webView
}

webView側

そして、JavaScriptのクリックイベントを追加します
viewDidLoad()の中の<button>を、以下のように編集します

-<button>Push Me</buton>
+<button onclick="window.webkit.messageHandlers.ToApp.postMessage('ButtonClicked')">Push Me</buton>

userContentController()の中に、ボタンをクリック後のやることを定義します

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
+	print("HTML Button is Clicked")
}

完成

これでHTMLボタンをクリックすれば、Swiftのデバッグパネルにメッセージが出てくることになりました

Discussion