最近项目里面用了一些h5的页面,然后避免不了,要跟网页交互。我用了UIwebView,也用了WKWebView。现在分别说下我自己的两种用法。
1、UIWebView:之前跟网页交互,基本就是拦截URL,跟前端的同事约好,拦截具有某些字符串的URL,可将携带的参数拼接在URL里面。主要就是实现 webview的这个代理方法。
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
guard let url = request.url, let q = URLComponents(url: url, resolvingAgainstBaseURL: true)?.queryItems else { return true }
if url.absoluteString.contain("homeworkStu/saveStuHomeworkAnswer") {
print("点击返回的链接是 == ",url)
var p = [String : Any]()
q.forEach({
if let v = $0.value {
p[$0.name] = v
}
})
self.saveAnwser(params: p)
return false
}
return true
}
我这里面实现的是,点击网页上面的某个按钮,然后我调用 saveAnwser()这个方法。我跟前端约定的就是,URL里面包含"homeworkStu/saveStuHomeworkAnswer"这个字符,然后将传给我的参数都拼接到URL里面,我自己再来解析出来。这种可能传参内容少,还可以。但是如果前端要传一个解析好的网络请求结果给我们,估计他们不愿意这种吧。
2、WKWebView:这种一样,也是要跟前端同事约定好,遵循 WKScriptMessageHandler 代理。
let config = WKWebViewConfiguration.init()
config.userContentController.add(self, name: "collectGzhu")
webView = WKWebView(frame: CGRect(x: 0, y: 0, width: UIScreen.w, height: app.isIphoneX ? (UIScreen.h - 88) : (UIScreen.h - 64)), configuration: config)
webView.navigationDelegate = self
webView.uiDelegate = self
webView.addObserver(self, forKeyPath: "estimatedProgress", options: NSKeyValueObservingOptions.new, context: nil)
self.view.addSubview(webView)
这里我跟前端同事约定的方法名就是 collectGzhu。然后就是实现这个代理方法。
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == "collectGzhu" {
print(message.body)
}
}
这种方法好像更简便一些,前端直接把要穿给我们的内容,放在body里面。
//js端代码实现实例(此处为js端实现代码给大家粘出来示范的!!!):
//window.webkit.messageHandlers.collectGzhu.postMessage({body: 'name=1212'});
还有拦截网页alert。就是实现这些代码方法。
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
self.alert(title: message, msg: message)
completionHandler()
}
func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
self.alert(title: message, msg: message)
completionHandler(true)
}
func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) {
self.alert(title: prompt, msg: prompt)
completionHandler(nil)
}
这里面的 completionHandler 回调必须写,我之前没写 completionHandler,一直崩溃,后来在网上找到的解决办法,就是要把completionHandler写上去。
网友评论