Search code examples
iosswiftwkwebviewwknavigationdelegate

Stop navigation WKWebview


This is my situation:

I have a view controller within a WKWebView. This webview starts with a page "A". In this page there are some links (href) and I want that for some of these links must open in the external browser.

For this reason I set the WKWebView delegate:

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

        if let url = webView.url?.absoluteString
        {

                if(self.isExternalURL(url))
                {
                    let urlT = URL(string: url)!
                    decisionHandler(.cancel)
                    UIApplication.shared.open(urlT, options: [:], completionHandler: nil)
                }
                else
                {
                    decisionHandler(.allow)
                }
         }
         else
         {
                decisionHandler(.allow)
         }
}

private func isExternalURL(url:String) -> Bool
{
    //......check link
}

My problem is that if I select an external link the external browser opens, but the webview does not remain on page A, but it also loads the external link while I would like it to remain on page A.

I dont know why


Solution

  • You should use navigationAction.request.url instead of webView.url

    • webView.url - Already loaded url
    • navigationAction.request.url - New url to load

    Change

    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        if let url = navigationAction.request.url?.absoluteString
        {
            if self.isExternalURL(url)
            {
                decisionHandler(.cancel)
                UIApplication.shared.open(navigationAction.request.url, options: [:], completionHandler: nil)
            }
            else
            {
                decisionHandler(.allow)
            }
        }
        else
        {
            decisionHandler(.allow)
        }
    }