将UIWebView委托迁移到WKWebView委托方法

我正在将UIWebView迁移到WKWebView。 我已经改变了所有的委托方法。 我需要WKWebView委托方法等于下面的UIWebView委托方法。 该应用程序工作正常。 但login会话不保留

UIWebView: extension WebViewController: UIWebViewDelegate { func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool { guard let url = request.url else { return true } guard !url.absoluteString.contains("data:application/pdf") else { navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.action, target: self, action: #selector(share(sender:))) return true } guard url.pathExtension != "pdf" else { let safariVC = SFSafariViewController(url: url) safariVC.modalPresentationStyle = .popover present(safariVC, animated: true, completion: nil) return false } guard url.isLogin() == false else { AppDelegate.navigationController.signOut(.sessionOnly) return false } guard let mobileSite = url.asMobileSite() else { return true } let mobileRedirect = URLRequest(url: mobileSite) webView.loadRequest(mobileRedirect) return false } func webViewDidStartLoad(_ webView: UIWebView) { numberOfDidStartLoads += 1 } func webViewDidFinishLoad(_ webView: UIWebView) { numberOfDidStartLoads -= 1 } func webView(_ webView: UIWebView, didFailLoadWithError error: Error) { numberOfDidStartLoads -= 1 } } 

我试着下面的代码,并获得会话过期。

 extension WebViewController: UIWebViewDelegate { func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (_: WKNavigationActionPolicy) -> Void) { guard let url = navigationAction.request.url else { decisionHandler(.allow) return } guard !url.absoluteString.contains("data:application/pdf") else { navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.action, target: self, action: #selector(share(sender:))) decisionHandler(.allow) return } guard url.pathExtension != "pdf" else { let safariVC = SFSafariViewController(url: url) safariVC.modalPresentationStyle = .popover present(safariVC, animated: true, completion: nil) decisionHandler(.cancel) return } guard url.isLogin() == false else { AppDelegate.navigationController.signOut(.sessionOnly) decisionHandler(.cancel) return } guard let mobileSite = url.asMobileSite() else { decisionHandler(.allow) return } let mobileRedirect = URLRequest(url: mobileSite) webView.load(mobileRedirect) decisionHandler(.cancel) return decisionHandler(.allow) } func webViewDidStartLoad(_ webView: UIWebView) { numberOfDidStartLoads += 1 } func webViewDidFinishLoad(_ webView: UIWebView) { numberOfDidStartLoads -= 1 } func webView(_ webView: UIWebView, didFailLoadWithError error: Error) { numberOfDidStartLoads -= 1 } } 

请帮我解决这个问题。 我已经在从UIWebView到WKWebView的代码中改变了一些错误。

您可能需要在代码中实现以下内容,这意味着不要使用UIWebViewDelegate协议尝试使用WKNavigationDelegate协议。 我想你在处理会话时缺less一个最重要的function。

  func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { print(#function) completionHandler(.performDefaultHandling,nil) } 

有不同types的AuthChallengeDisposition ,像

 public enum AuthChallengeDisposition : Int { case useCredential case performDefaultHandling case cancelAuthenticationChallenge case rejectProtectionSpace } 

完整的WKNavigationDelegate协议是

  extension ViewController: WKNavigationDelegate{ func webViewWebContentProcessDidTerminate(_ webView: WKWebView) { print(#function) } func webView(_ webView: WKWebView, didCommit navigation: WKNavigation!) { print(#function) } func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) { print(#function) } func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { print(#function) } func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) { print(#function) } func webView(_ webView: WKWebView, didReceiveServerRedirectForProvisionalNavigation navigation: WKNavigation!) { print(#function) } func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: Error) { print(#function) } func webView(_ webView: WKWebView, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { print(#function) completionHandler(.performDefaultHandling,nil) } func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { print(#function) decisionHandler(.allow) } func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) { print(#function) decisionHandler(.allow) } } 

我想你可以使用webView(_:decidePolicyFor:decisionHandler:)并阻止/取消或允许请求。 这应该以同样的方式工作。

免责声明:我还没有testing过,我会尽快find答案。

分析你的代码,我发现了一个从来没有达到的“返回”原因之前调用的声明。

声明是:

 decisionHandler(.allow) 

你可以find它作为函数的最后一行代码:

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

你有这个方法:

 func webViewDidStartLoad(_ webView: UIWebView) { numberOfDidStartLoads += 1 }