iOS调用JS
iOS调用的代码
// JSMethod为js端定义的参数,parameter为给js端传递的参数
// 如果参数只有一个可以直接传递字符串,多个应该传递json
webView?.evaluateJavaScript(“JSMethod('parameter')”, completionHandler: { (result, error) in
debugPrint("result", result ?? "")
debugPrint("error", error ?? "" )
})
JS端的代码
<script>
function JSMethod(parameter) {
}
</script>
可能的失败原因
1.iOS端调用方法应该在H5页面加载完成后(estimatedProgress == 1),不应该在viewDidLoad中就调用,否则会报无此方法。
2.JS端必须将该方法定为全局的方法,如果放在某一个对象里,可能安卓可以调用,但是iOS无法调用。
3.JS端一般会将iOS和安卓的方法分为两套,注意与JS端沟通,不是安卓可以调用iOS端就可以调用。
JS调用iOS
iOS端实现代码
1.iOS端需要注册给JS调用的方法,如下:
webView?.configuration.userContentController.add(self, name: "iOSMethod")
2.iOS端在WKScriptMessageHandler中接收js端调用改方法以及可能传递过来的参数,如果是多个参数js端要定义成为json格式,无参数至少要传递一个null,接收协议如下:
extension WebViewViewModel:WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
debugPrint("body==" , message.body, "name==" + message.name)
}
}
3.iOS端需要移除该方法:
webView?.configuration.userContentController.removeScriptMessageHandler(forName: "iOSMethod")
JS端调用iOS
注意:无论是否要给iOS传递参数,都必须要传递一个至少null或者空字符串等,否则iOS无法接收。
window.webkit.messageHandlers.iOSMethod.postMessage("");
可能失败原因
1.JS端调用方法,但是什么都没有传递,null都没有传递。
WKWebView获取title与进度条
1.注册监听监听。
self.wkWebView?.addObserver(self, forKeyPath: "estimatedProgress", options: NSKeyValueObservingOptions.new, context: nil)
self.wkWebView?.addObserver(self, forKeyPath: "title", options: NSKeyValueObservingOptions.new, context: nil)
2.监听改变时,progressView为自己的进度条,title为获取js的title.
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if(keyPath == "estimatedProgress") {
self.progressView.isHidden = self.wkWebView!.estimatedProgress == 1
self.progressView.setProgress(Float(self.wkWebView!.estimatedProgress), animated: false)
}
if keyPath == "title" {
if(self.controllerTitle == "加载中...") {
self.navigationItem.title = self.wkWebView?.title
}
}
}
3.移除监听:
self.wkWebView?.removeObserver(self, forKeyPath: "estimatedProgress")
self.wkWebView?.removeObserver(self, forKeyPath: "title")
注意事项:因为UIViewController可能会被从父视图移除,所以wkWebView要是可选值,否则在deinit销毁时会造成崩溃。
WKWebView与UIWebView的区别
主要是内存存在区别,WKWebView使用的内存空间是单独开辟的,而UIWebView使用的是应用程序程序的,一旦发生内存崩溃,WKWebView只会白屏,而UIWebView则会直接退出应用程序。
WkWebView的一些问题
1.加载游戏容易出现缓存导致代码不生效,如果发现游戏一直缓存可以修改版本号在发布。
2.WebView内存不够怎么办?有的老版本手机很容易出现白屏,只有监控内存即将溢出时,可以重新刷新webView,只是会容易存在反复加载。