WKWebView与JS的交互

1,458 阅读2分钟

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,只是会容易存在反复加载。