收藏ios

WKWebView的使用

2016-04-26  本文已影响1135人  流星大石头

WKWebView是iOS8.0之后引入的,不再打算适配iOS7.0的小伙伴可以尝试使用一下这个WKWebView这个控件。

WKWebView与UIWebView的一个简单的对比
WKWebView的使用介绍
//执行js语句
 open func evaluateJavaScript(_ javaScriptString: String, completionHandler: ((Any?, Error?) -> Swift.Void)? = nil)

注意:在以后的开发中,如果遇到代理方法的block回调是handler的一定要实现这个回调,否则会直接报错。

//MARK:在发送请求之前,决定是否跳转
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    decisionHandler(.allow)
}
//MARK:收到响应后决定是否跳转
func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
    decisionHandler(.allow)
}
//MARK:接收到服务器跳转请求之后调用
func webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) {
}

//MARK:页面开始加载时调用
func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
}
//MARK:当内容开始返回时调用
func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
}
//MARK:页面加载完成之后调用
func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
}
//MARK:页面加载失败时调用
func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
}
在WKWebview中,js的alert是不会出现任何内容的,你必须重写WKUIDelegate委托的runJavaScriptAlertPanelWithMessage message方法,自己处理alert。类似的还有Confirm和prompt也和alert类似,这里我只以alert为例。
//接收js alert
func webView(_ webView: WKWebView, runJavaScriptAlertPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping () -> Void) {
    completionHandler()
    printlndebug("alert:\(message)")
    //        let alert = UIAlertController(title: "", message: message, preferredStyle: .alert)
    //        alert.addAction(UIAlertAction(title: "确定", style: .default, handler: nil))
    //        self.present(alert, animated: true, completion: nil)
}
//接收js confirm
func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
    //        let alert = UIAlertController(title: "", message: message, preferredStyle: .alert)
    //        let ok = UIAlertAction(title: "确定", style: .default) { (action) in
    //            completionHandler(true)
    //        }
    //        let cancel = UIAlertAction(title: "取消", style: .cancel) { (action) in
    //            completionHandler(false)
    //        }
    //        alert.addAction(ok)
    //        alert.addAction(cancel)
    //        self.present(alert, animated: true, completion: nil)
    printlndebug("confirm:\(message)")
}
//接收js prompt
func webView(_ webView: WKWebView, runJavaScriptTextInputPanelWithPrompt prompt: String, defaultText: String?, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (String?) -> Void) {
    printlndebug("prompt:\(prompt)")
    
}
关于WKWebView的清理缓存问题

WKWebView是在ios8.0之后推出的,但是清理缓存的功能是在ios9.0之后推出的。所以要判断一下系统的版本,否则可能会导致程序崩溃

        if #available(iOS 9.0, *) {
            let types:Set = [WKWebsiteDataTypeMemoryCache,WKWebsiteDataTypeDiskCache]
            let dateFrom = Date(timeIntervalSince1970: 0)
            WKWebsiteDataStore.default().removeData(ofTypes: types, modifiedSince: dateFrom, completionHandler: { 
        })
        } else {
            // Fallback on earlier versions
            let libraryPath = NSSearchPathForDirectoriesInDomains(.userDirectory, .userDomainMask, true).last
            if let cookies = libraryPath?.appending("/Cookies") {
                do {
                    try FileManager.default.removeItem(atPath: cookies)
                } catch {
                }
            }
        }
关于WKWebView的跨域问题:

WebKit框架对跨域进行了安全性检查限制,不允许跨域,比如从一个 HTTP 页对 HTTPS 发起请求是无效的(有一个界面要跳到支付宝页面去支付,死活没反应)
但是WebKit对跨域进行了安全检查限制,不允许跨域,所以要对需要跨域的链接进行单独处理。

func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    var policy = WKNavigationActionPolicy.allow
    if let url = navigationAction.request.url,WKNavigationType.linkActivated == navigationAction.navigationType && url.scheme == "https" {
        UIApplication.shared.open(url, options: [:], completionHandler: { (flag) in
            policy = WKNavigationActionPolicy.cancel
        })
    }
    decisionHandler(policy)
}

更多关于使用WKWebView需要注意的坑,请参考:WKWebView 那些坑

参考文档:
1.UIWebView和WKWebView的使用及js交互
2.WKWebView微信适配
3.iOS9WKWebView清除缓存
4.WKWebView走过的10个坑

上一篇 下一篇

猜你喜欢

热点阅读