External links in WebView to external Safari browser

Hi,

I have a WebView based app, I want any external links within the default website in the WebView to open in a new Safari browser tab rather than within the Website I am displaying through the app.

In the ViewController, I have:

import UIKit import WebKit import CoreLocation

class ViewController: UIViewController, WKNavigationDelegate { var webView: WKWebView!

override func loadView() {
    webView = WKWebView()
    webView.navigationDelegate = self
    view = webView
    let url = URL(string: "https://domain.com")!
    webView.load(URLRequest(url: url))
    webView.allowsBackForwardNavigationGestures = true
    webView.navigationDelegate = self
}
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    if let url = navigationAction.request.url {
        if url.host != "https://domain.com" {
            UIApplication.shared.open(url)
            decisionHandler(.cancel)
            return
        }
    }
    decisionHandler(.allow)
}}

But, rather than it opening a new Safari browser when you tap onto an external link, when the app launches, the website I have contained within the app opens in Safari.

Is there anything I can do to try and resolve this issue?

Any help is appreciated.

Answered by dafo in 714197022

I have a feeling this is what is working:


import UIKit
import WebKit
import CoreLocation

class ViewController: UIViewController, WKNavigationDelegate {
    var webView: WKWebView!

    override func loadView() {
        webView = WKWebView()
        view = webView
        let url = URL(string: "https://domain.com")!
        webView.load(URLRequest(url: url))
        webView.allowsBackForwardNavigationGestures = true
        webView.navigationDelegate = self
    }
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
                if navigationAction.navigationType == .linkActivated  {
                    if let url = navigationAction.request.url,
                    let host = url.host, host.hasPrefix("domain.com") !=
                        UIApplication.shared.canOpenURL(url) {
                            UIApplication.shared.open(url)
                            decisionHandler(.cancel)
                    } else {
                        // Open in web view
                        decisionHandler(.allow)
                    }
                } else {
                    // other navigation type, such as reload, back or forward buttons
                    decisionHandler(.allow)
                }
            }
    }

This seems to be working as I would expect.

OK, I have sussed it.

First, in the info.plist I added:

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSExceptionDomains</key>
  <dict>
    <key>yourserver.com</key>
    <dict>
      <!--Include to allow subdomains-->
      <key>NSIncludesSubdomains</key>
      <true/>
      <!--Include to allow HTTP requests-->
      <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
      <true/>
      <!--Include to specify minimum TLS version-->
      <key>NSTemporaryExceptionMinimumTLSVersion</key>
      <string>TLSv1.1</string>
    </dict>
  </dict>
</dict>

Then in the ViewController, it now looks like:

import UIKit
import WebKit
import CoreLocation

class ViewController: UIViewController, WKNavigationDelegate {
    var webView: WKWebView!

    override func loadView() {
        webView = WKWebView()
        webView.navigationDelegate = self
        view = webView
        let url = URL(string: "https://domain.com")!
        webView.load(URLRequest(url: url))
        webView.allowsBackForwardNavigationGestures = true
        webView.navigationDelegate = self
    }
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
            if navigationAction.navigationType == .linkActivated  {
                if let url = navigationAction.request.url,
                    UIApplication.shared.canOpenURL(url) {
                        UIApplication.shared.open(url)
                        decisionHandler(.cancel)
                } else {
                    // Open in web view
                    decisionHandler(.allow)
                }
            } else {
                // other navigation type, such as reload, back or forward buttons
                decisionHandler(.allow)
            }
        }
}

And so far, it works.

Accepted Answer

I have a feeling this is what is working:


import UIKit
import WebKit
import CoreLocation

class ViewController: UIViewController, WKNavigationDelegate {
    var webView: WKWebView!

    override func loadView() {
        webView = WKWebView()
        view = webView
        let url = URL(string: "https://domain.com")!
        webView.load(URLRequest(url: url))
        webView.allowsBackForwardNavigationGestures = true
        webView.navigationDelegate = self
    }
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
                if navigationAction.navigationType == .linkActivated  {
                    if let url = navigationAction.request.url,
                    let host = url.host, host.hasPrefix("domain.com") !=
                        UIApplication.shared.canOpenURL(url) {
                            UIApplication.shared.open(url)
                            decisionHandler(.cancel)
                    } else {
                        // Open in web view
                        decisionHandler(.allow)
                    }
                } else {
                    // other navigation type, such as reload, back or forward buttons
                    decisionHandler(.allow)
                }
            }
    }

This seems to be working as I would expect.

the code is working but all links redirect to safari

how do i make only externals to redirect to safari ?

External links in WebView to external Safari browser
 
 
Q