實現(xiàn)效果:
以最簡單的形式與最簡單的demo來實現(xiàn)WKWebView與HTML文件的JS交互方式.
包括Swift調用JS方法以及JS調用Swift原生方法.并傳遞各種類型參數
實現(xiàn)在控制臺打印JS中的Console.log內容.
1.添加WeakScriptMessageDelegate文件,用其作為與JS交互時的代理,防止出現(xiàn)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發(fā)消息的時候會用到
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.實現(xiàn)調用JS方法
讓控制器實現(xiàn)WKNavigationDelegate協(xié)議
extension ViewController: WKNavigationDelegate{
///在網頁加載完成時調用js方法
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
webView.evaluateJavaScript("sayHello('js你好,我是從Swift傳來的')", completionHandler: nil)
}
}
5.接收JS調用方法
讓控制器實現(xiàn)WKScriptMessageHandler協(xié)議
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
}
}
}
截止以上功能已經全部實現(xiàn),接下來講一下與h5協(xié)同調試時很重要一部分,就是打印出JS方法中console.log的內容,這樣才能即時的,直觀的了解交互情況.安卓方面自帶了這個功能,但是WKWebView需要我們與H5同時添加代碼才能夠實現(xiàn).
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
}
}
demo地址:WKWebView-Script
使用WKWebView與H5交互還是很簡單的,如果需要可以先在本地實現(xiàn),然后把html文件給做H5的同事參考一下.雙方多交流相信可以很快實現(xiàn).
有問題歡迎探討.