天天看點

學習筆記:WKWebView之WKNavigationDelegate (Swift)

WKWebView之WKNavigationDelegate (Swift)

此代理實作的方法可以用來追蹤加載過程(頁面開始加載、加載完成、加載失敗)、決定是否執行跳轉。

WKNavigationDelegate:

1、下面的方法在跳轉時觸發

    在接到請求位址,未開始請求前

    optionalpublicfunc webView(_ webView:WKWebView, decidePolicyFor navigationAction:WKNavigationAction, decisionHandler:@escaping (WKNavigationActionPolicy) -> Swift.Void)

    允許請求,開始請求

    optionalpublicfunc webView(_ webView:WKWebView, decidePolicyFor navigationResponse:WKNavigationResponse, decisionHandler:@escaping (WKNavigationResponsePolicy) -> Swift.Void)

    主機位址被重新定位時觸發

    optional public func webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!)

2、下面的個方法分别用來追蹤加載過程:

       頁面開始加載

    optional public func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!)

 頁面加載失敗

    optionalpublicfunc webView(_ webView:WKWebView, didFailProvisionalNavigation navigation:WKNavigation!, withError error: Error)*)

頁面送出内容

    optionalpublicfunc webView(_ webView:WKWebView, didCommit navigation:WKNavigation!)

頁面完成加載

    optionalpublicfunc webView(_ webView:WKWebView, didFinish navigation:WKNavigation!)

頁面加載内容失敗

    optionalpublicfunc webView(_ webView:WKWebView, didFail navigation:WKNavigation!, withError error: Error)

    在需要獲驗證書時*)

    optionalpublicfunc webView(_ webView:WKWebView, didReceive challenge:URLAuthenticationChallenge, completionHandler:@escaping (URLSession.AuthChallengeDisposition,URLCredential?) -> Swift.Void)

    @available(iOS9.0, *)

    optionalpublicfunc webViewWebContentProcessDidTerminate(_ webView:WKWebView)

具體實作和觸發時機代碼注釋中有詳細使用:

//MARK: - WKNavigationDelegate
    /**
     執行層級:①
     webView發起請求之前調用
     allow後才會進行後面的代理方法
     decisionHandler 必須執行
     - parameter webView:          響應webView
     - parameter navigationAction: 包含響應事件的資訊對象
     - parameter decisionHandler:  回調block,參數:allow or cancel
     */
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        debugPrint("class: \(object_getClassName(self))" + #function + "LINE: \(#line)")
       
        decisionHandler(.allow)
    }
    /**
     執行層級:③
     URL響應正确,接收到相應資料後,決定是否跳轉
     decisionHandler 必須執行
     - parameter webView:            響應webView
     - parameter navigationResponse: 請求位址
     - parameter decisionHandler:    回調block,參數:allow or cancel
     */
    func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
        debugPrint("class: \(object_getClassName(self))" + #function + "LINE: \(#line)")
        decisionHandler(WKNavigationResponsePolicy.allow)
        
    }
    /**
     執行層級:②
     允許請求後開始
     
     - parameter webView:    響應webView
     - parameter navigation: navigation
     */
    func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {
        debugPrint("class: \(object_getClassName(self))" + #function + "LINE: \(#line)")
    }
    /**
     主機位址被重定向時調用
     
     - parameter webView:    webView description
     - parameter navigation: navigation description
     */
    func webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) {
        debugPrint("class: \(object_getClassName(self))" + #function + "LINE: \(#line)")
    }
    /**
     執行層級:④
     頁面加載失敗時調用
     
     - parameter webView:    響應webView
     - parameter navigation: navigation
     - parameter error:      error
     */
    func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) {
        debugPrint(#function + "\nerror: \(error.localizedDescription)")
    }
    /**
     執行層級:④
     當内容開始傳回時調用
     
     - parameter webView:    webView description
     - parameter navigation: navigation description
     */
    func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) {
        debugPrint("class: \(object_getClassName(self))" + #function + "LINE: \(#line)")
        
    }
    /**
     執行層級:⑤
     内容接受完畢後(JS等執行完畢後,在此之前執行 WKUIDelegate 的對應方法)
     
     - parameter webView:    webView
     - parameter navigation: navigation
     */
    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        self.webPlaceholderView.addSubview(self.webView)
        self.navigationItem.title = webView.title;
        debugPrint("class: \(object_getClassName(self))" + #function + "LINE: \(#line)")
        self.webView.evaluateJavaScript("myFunction()") { (object, error) in
            
        }
    }
    /**
     跳轉失敗時調用
     
     - parameter webView:    webView description
     - parameter navigation: navigation description
     - parameter error:      error description
     */
    func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {
        debugPrint("class: \(object_getClassName(self))" + #function + "LINE: \(#line)")
        
    }
    /**
     在通路資源的時候,如果伺服器傳回需要授權(提供一個NSURLCredential對象)
     
     - parameter webView:           webView description
     - parameter challenge:         challenge description
     - parameter completionHandler:   completionHandler description
     */
    func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
        
        debugPrint("class: \(object_getClassName(self))" + #function + "LINE: \(#line)")
        
        // 認證伺服器證書
        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
            debugPrint("獲得服務端證書認證!")
            completionHandler(.performDefaultHandling, nil)
            /*
             /*
                将服務端證書與本地證書對比
             */
            completionHandler(.performDefaultHandling, nil)
            let serverTrust:SecTrust = challenge.protectionSpace.serverTrust!
            let certificate = SecTrustGetCertificateAtIndex(serverTrust, 0)!
            let remoteCertificateData
                = CFBridgingRetain(SecCertificateCopyData(certificate))!
            let cerPath = Bundle.main.path(forResource: "tomcat", ofType: "cer")!
            let localCertificateData = NSData(contentsOfFile:cerPath)!
            // 對比證書
            if (remoteCertificateData.isEqual(to: localCertificateData as Data) == true) {
             // 将用戶端證書傳回給服務端
                let credential = URLCredential.init(trust: serverTrust)
                challenge.sender?.use(credential,
                                      for: challenge)
                completionHandler(.useCredential,
                                  URLCredential.init(trust: challenge.protectionSpace.serverTrust!))
                
            } else {
             // 認證不通過取消請求
                completionHandler(.cancelAuthenticationChallenge, nil)
            }
             */
        }else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate{
            debugPrint("用戶端證書認證!")
            //擷取用戶端證書相關資訊
            
            completionHandler(.useCredential, nil);
        }else {
            debugPrint("其它情況(不接受認證)")
            completionHandler(.cancelAuthenticationChallenge, nil);
        }
        
    }
    /**
     9.0 later,web内容進行中斷時會觸發
     
     - parameter webView: webView description
     */
    func webViewWebContentProcessDidTerminate(_ webView: WKWebView) {
       debugPrint("class: \(object_getClassName(self))" + #function + "LINE: \(#line)")
    }
           

連結: 1.對于WKWebView的整理: 具體使用

          2.WKUIDelegate:具體使用

具體使用的Demon(持續更新中):Demon(持續更新中)