26

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.

Siva
  • 1,848
  • 2
  • 23
  • 40
  • Possible duplicate of [Migrating from UIWebView to WKWebView](https://stackoverflow.com/questions/37509990/migrating-from-uiwebview-to-wkwebview) – Tamás Sengel Sep 12 '17 at 08:40
  • can you give more info about the crash? you must call `decisionHandler` in this method, can the crash be related to that? – Mert Buran Sep 12 '17 at 09:05
  • No. 'App Delegate' Crash. I have added screenshot please see @MertBuran – Siva Sep 12 '17 at 09:10
  • do you have an exception breakpoint while debugging? `AppDelegate` shouldn't be crashing here – Mert Buran Sep 12 '17 at 09:46
  • No Exception breakpoint. – Siva Sep 12 '17 at 09:49
  • @MertBuran Any idea? – Siva Sep 12 '17 at 13:13
  • i mean you should add an "exception breakpoint" (you can google it with these keywords) to see which line actually crashes, then you can dig deeper to fix the crash. btw, looks like your original question is answered; now you are asking another question. i'd suggest you asking another question on SO instead of merging two different questions into one. hope that helps – Mert Buran Sep 12 '17 at 16:33
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/154307/discussion-between-siva-and-mert-buran). – Siva Sep 13 '17 at 08:19
  • I do not understand the actual issue. How I understand, the app crashes in AppDelegate and you do not know why? Is this correct? Or is `session` nill at some point ("login session is not retaining")? – shallowThought Sep 17 '17 at 10:09
  • @shallowThought The issue is session is not retaining. – Siva Sep 18 '17 at 04:43

4 Answers4

8

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)
    }
}
Jayachandra A
  • 1,335
  • 1
  • 10
  • 21
2

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.

Mert Buran
  • 2,989
  • 2
  • 22
  • 34
1

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

UIwebview depreciated its new app release to app store you can use the UIWebview app can rejected so please once check and update to WKwebview

----------------- UIWebViewDelegate Delegates -------------

func webViewDidStartLoad(_ webView: UIWebView) { }

func webViewDidFinishLoad(_ webView: UIWebView) { }

func webView(_ webView: UIWebView, didFailLoadWithError error: Error) { }

--------------- Replace the WKNavigationDelegate Delegates--------------

func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) {}

func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {}

func webView(_ webView: WKWebView, didFail navigation: WKNavigation!, withError error: Error) {}

Community
  • 1
  • 1
Srinivasan_iOS
  • 972
  • 10
  • 12