简体   繁体   English

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

[英]Migrating UIWebView delegate to WKWebView delegate method

I am working on migrating UIWebView to WKWebView. 我正在努力将UIWebView迁移到WKWebView。 I have changed all the Delegate methods. 我已经更改了所有Delegate方法。 I need WKWebView delegate methods equal to below UIWebView delegate method. 我需要WKWebView委托方法等于下面的UIWebView委托方法。 The app is working fine. 该应用程序运行正常。 but login session is not retaining 但是登录会话没有保留

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
}
}

And i tried below code and getting session expire. 我尝试下面的代码,让会话到期。

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
    }
}

Please help me to resolve this issue. 请帮我解决这个问题。 I have made some mistake in changing code from UIWebView to WKWebView. 我在将代码从UIWebView更改为WKWebView时犯了一些错误。

You might required to implement the following in your code, which means instead of using UIWebViewDelegate protocol try to use WKNavigationDelegate protocol. 您可能需要在代码中实现以下内容,这意味着不要使用UIWebViewDelegate协议尝试使用WKNavigationDelegate协议。 I guess you are missing one of the most important function when you are handling with sessions . 我猜你在处理会话时缺少一个最重要的功能。

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

There are different types of AuthChallengeDisposition , like 有不同类型的AuthChallengeDisposition ,比如

public enum AuthChallengeDisposition : Int {


    case useCredential

    case performDefaultHandling

    case cancelAuthenticationChallenge

    case rejectProtectionSpace
}

Complete WKNavigationDelegate protocols are 完整的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)
    }
}

I guess you can use webView(_:decidePolicyFor:decisionHandler:) and you block/cancel or allow requests. 我想你可以使用webView(_:decidePolicyFor:decisionHandler:)并阻止/取消或允许请求。 That should work in the same way. 这应该以同样的方式起作用。

Disclaimer: I haven't tested that yet, I'll do so as soon as I find some time. 免责声明:我还没有测试过,我会在找到一些时间后立即进行测试。

analyzing your code, i have found a statement that is never reached cause of "return" called before. 在分析你的代码时,我发现了一个永远不会达到之前调用的“返回”的语句。

The statement is: 声明是:

decisionHandler(.allow)

You can find it as last line of code for the function: 您可以在函数的最后一行代码中找到它:

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

that you have up this method: 你有这个方法:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM