Swift.WKWebView與Html檔案的JS互動
阿新 • • 發佈:2018-12-21
實現效果:
以最簡單的形式與最簡單的demo來實現WKWebView與HTML檔案的JS互動方式.
包括Swift呼叫JS方法以及JS呼叫Swift原生方法.並傳遞各種型別引數
實現在控制檯列印JS中的Console.log內容.
1.新增WeakScriptMessageDelegate檔案,用其作為與JS互動時的代理,防止出現ViewController不釋放的問題.
import UIKit import WebKit ///記憶體管理,使用delegate類防止ViewController不釋放 class WeakScriptMessageDelegate: NSObject, WKScriptMessageHandler { weak var scriptDelegate: WKScriptMessageHandler? init(_ scriptDelegate: WKScriptMessageHandler) { self.scriptDelegate = scriptDelegate super.init() } func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) { scriptDelegate?.userContentController(userContentController, didReceive: message) } deinit { print("WeakScriptMessageDelegate is deinit") } }
2.宣告WKWebView,並註冊與JS互動的名稱.
lazy var webView: WKWebView = { ///偏好設定 let preferences = WKPreferences() preferences.javaScriptEnabled = true let configuration = WKWebViewConfiguration() configuration.preferences = preferences configuration.selectionGranularity = WKSelectionGranularity.character configuration.userContentController = WKUserContentController() // 給webview與swift互動起名字,webview給swift發訊息的時候會用到 configuration.userContentController.add(WeakScriptMessageDelegate(self), name: "logger") configuration.userContentController.add(WeakScriptMessageDelegate(self), name: "redResponse") configuration.userContentController.add(WeakScriptMessageDelegate(self), name: "blueResponse") configuration.userContentController.add(WeakScriptMessageDelegate(self), name: "greenResponse") configuration.userContentController.add(WeakScriptMessageDelegate(self), name: "yellowResponse") var webView = WKWebView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height), configuration: configuration) // 讓webview翻動有回彈效果 webView.scrollView.bounces = false // 只允許webview上下滾動 webView.scrollView.alwaysBounceVertical = true webView.navigationDelegate = self return webView }()
3.Html檔案樣式
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0,user-scalable=no"/> </head> <body> 名字:<span id="name"></span> <br/> <button style = "background-color: #ff0000;color: #FFFFFF;padding: 15px 32px;" onclick="redResponse()">紅色</button> <button style = "background-color: #0041ff;color: #FFFFFF;padding: 15px 32px;" onclick="blueResponse()">藍色</button> <button style = "background-color: #00d819;color: #FFFFFF;padding: 15px 32px;" onclick="greenResponse()">綠色</button> <button style = "background-color: #ffe064;color: #FFFFFF;padding: 15px 32px;" onclick="yellowResponse()">黃色</button> <!-- 新增這個script在專案頭,這樣swift才能列印console.log的內容 --> <script> var console = {}; console.log = function(message){window.webkit.messageHandlers['logger'].postMessage(message) }; </script> <script type="text/javascript"> ///被swift呼叫的方法 function sayHello(text) { console.log(text) } ///呼叫swift方法的方式 window.webkit.messageHandlers.(swift註冊的互動名).postMessage(傳給swift的引數) function redResponse() { ///沒有引數傳可以傳任意值,讓swift端不接收 window.webkit.messageHandlers.redResponse.postMessage("") } function blueResponse() { window.webkit.messageHandlers.blueResponse.postMessage("藍色") } function greenResponse() { window.webkit.messageHandlers.greenResponse.postMessage(1) } function yellowResponse() { window.webkit.messageHandlers.yellowResponse.postMessage(["1","2","3"]) } </script> </body> </html>
4.實現呼叫JS方法
讓控制器實現WKNavigationDelegate協議
extension ViewController: WKNavigationDelegate{
///在網頁載入完成時呼叫js方法
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
webView.evaluateJavaScript("sayHello('js你好,我是從Swift傳來的')", completionHandler: nil)
}
}
5.接收JS呼叫方法
讓控制器實現WKScriptMessageHandler協議
extension ViewController: WKScriptMessageHandler{
///接收js呼叫方法
func userContentController(_ userContentController: WKUserContentController,
didReceive message: WKScriptMessage) {
///在控制檯中列印html中console.log的內容,方便除錯
let body = message.body
if message.name == "logger" {
print("JS log:\(body)")
return
}
///message.name是約定好的方法名,message.body是攜帶的引數
switch message.name {
case "redResponse":
///不接收引數時直接不處理message.body即可,不用管Html傳了什麼
redRequest()
case "blueResponse":
blueRequest(string: message.body as! String)
case "greenResponse":
greenRequest(int: message.body as! Int)
case "yellowResponse":
yellowRequest(array: message.body as! [String])
default:
break
}
}
}
####截止以上功能已經全部實現,接下來講一下與h5協同除錯時很重要一部分,就是打印出JS方法中console.log的內容,這樣才能即時的,直觀的瞭解互動情況.安卓方面自帶了這個功能,但是WKWebView需要我們與H5同時新增程式碼才能夠實現. ######1.在html檔案中宣告console
<!-- 新增這個script在專案頭,這樣swift才能列印console.log的內容 -->
<script>
var console = {};
console.log = function(message){window.webkit.messageHandlers['logger'].postMessage(message)
};
</script>
<script type="text/javascript">
######2.在swift檔案中宣告webView時使用configuration註冊與JS互動名
configuration.userContentController.add(WeakScriptMessageDelegate(self), name: "logger")
######3.在swift檔案中接收方法裡新增
///接收js呼叫方法
func userContentController(_ userContentController: WKUserContentController,
didReceive message: WKScriptMessage) {
///在控制檯中列印html中console.log的內容,方便除錯
let body = message.body
if message.name == "logger" {
print("JS log:\(body)")
return
}
}
使用WKWebView與H5互動還是很簡單的,如果需要可以先在本地實現,然後把html檔案給做H5的同事參考一下.雙方多交流相信可以很快實現.
有問題歡迎探討.