技术要点
html通过js向iOS原生传递消息
window.webkit.messageHandlers.InjectHTML.postMessage({title: "输入框失去焦点", message:input.target.value, id: input.target.id});
注:InjectHTML是和iOS原生约定的一个string标识
原生如何收到对应事件
初始化WKWebView
//初始化 Configuration
let configuration = WKWebViewConfiguration()
configuration.userContentController = WKUserContentController()
// 给Configuration 增加一个js script处理器
// 采用了中间层的因素,避免循环引用导致无法释放问题
//WKScriptMessageHandler
configuration.userContentController.add(ScriptHandler(delegate: self), name: ViewController.scriptKey)
//configuration.userContentController.add(self, name: ViewController.scriptKey)
webview = WKWebView(frame: frame, configuration: configuration)
view.addSubview(webview)
实现WKScriptMessageHandler协议
// 遵守协议
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
// 因html可能传递多种类型名称,我们这里须指定key
if message.name == ViewController.scriptKey {
guard let dic = message.body as? [String: String] else {
return
}
// 交给真实处理解析函数
receiveInputValue(para: dic)
}
}
// 解析函数可以负责更具体的内容,因为demo,故此只是打印
func receiveInputValue(para: [String: String]) {
let title = para["title"] ?? "无值"
let message = para["message"] ?? "无值"
let `id` = para["id"] ?? "无值"
print("title: \(title)")
print("message: \(message)")
print("id: \(id)")
}
原生如何将代码注入到html里面
从文件读取js代码,转换为string字符串
guard let jsString = try? String(contentsOfFile: Bundle.main.path(forResource: "Inject", ofType: "js") ?? "") else {
// 没有读取出来则不执行注入
return
}
// 注入语句
webView.evaluateJavaScript(jsString, completionHandler: { _, _ in
print("代码注入成功")
})