1. 程式人生 > >學習筆記:WKWebView之WKNavigationDelegate (Swift)

學習筆記:WKWebView之WKNavigationDelegate (Swift)

//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)")
    }