0

Im getting this error when i press any link.

Completion handler passed to -[webView:decidePolicyForNavigationAction:decisionHandler:] was called more than once

The link open in safari but the app chrash.

Any suggestions ?

import UIKit
import WebKit

class Polering: UIViewController, WKNavigationDelegate {
    // Connect the webView from the StoryBoard.
    @IBOutlet weak var webView: WKWebView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Get the path of the index.html
        guard let htmlPath = Bundle.main.path(forResource: "index", ofType: "html", inDirectory: "www") else {
            return
        }
        // Create an URL to load it in the webView.
        let url = URL(fileURLWithPath: htmlPath)
        let request = URLRequest(url: url)
        webView.navigationDelegate = self
        webView.load(request)
    }

    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        // Check for links.
        if navigationAction.navigationType == .linkActivated {
            // Make sure the URL is set.
            guard let url = navigationAction.request.url else {
                decisionHandler(.cancel)
                return
            }

            // Check for the scheme component.
            let components = URLComponents(url: url, resolvingAgainstBaseURL: false)
            if components?.scheme == "http" || components?.scheme == "https" {

                if navigationAction.targetFrame == nil {
                    UIApplication.shared.open(url)
                    decisionHandler(.cancel)
                    return
                } else {
                    decisionHandler(.allow)
                }

                // Open the link in the external browser.
                UIApplication.shared.open(url)
                // Cancel the decisionHandler because we managed the navigationAction.
                decisionHandler(.cancel)
                return
            } else {
                decisionHandler(.allow)
            }
        } else {
            decisionHandler(.allow)
        }
    }
}

1 Answers1

0

Because decisionHandler is being called 2 times. It must be called once.

if navigationAction.targetFrame == nil {
    UIApplication.shared.open(url)
    decisionHandler(.cancel)
    return
} else {
    // =======> First time here
    decisionHandler(.allow)
}

// Open the link in the external browser.
UIApplication.shared.open(url)
// Cancel the decisionHandler because we managed the navigationAction.
// =======> Second time here
decisionHandler(.cancel)

you can revise the logic fix duplicate calls to decisionHandler.

If logic is correct, just comment the decisionHandler line in else part.

if navigationAction.targetFrame == nil {
    UIApplication.shared.open(url)
    decisionHandler(.cancel)
    return
}

UIApplication.shared.open(url)
decisionHandler(.cancel)
Bilal
  • 18,478
  • 8
  • 57
  • 72