简体   繁体   中英

Migrating UIWebView delegate to WKWebView delegate method

I am working on migrating UIWebView to WKWebView. I have changed all the Delegate methods. I need WKWebView delegate methods equal to below UIWebView delegate method. 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.

You might required to implement the following in your code, which means instead of using UIWebViewDelegate protocol try to use WKNavigationDelegate protocol. 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

public enum AuthChallengeDisposition : Int {


    case useCredential

    case performDefaultHandling

    case cancelAuthenticationChallenge

    case rejectProtectionSpace
}

Complete WKNavigationDelegate protocols are

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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