While some of the above solutions worked to an extent, the issue was that all the links started to open externally not just the ones where the HTTPs url scheme was not followed like mailto, blank, deeplinks etc.
I implement these WKNavigationDelegate
functions
decidePolicyFor navigationAction
(documentation link) to allow even urls that do not follow the HTTPs scheme to be allowed to be processed
this navigation fail delegate function webView didFailProvisionalNavigation
and check if iOS can handle the open in a new tab, mail, deep link etc so in your case it would open the app store
You could also implement the same logic as point 2 in this
WKNavigationDelegate function just in case
Here is the code:
class ViewController: UIViewController, WKNavigationDelegate
{
// Initialize the webview anywhere you wish
override func viewDidAppear(_ animated: Bool)
{
super.viewDidAppear(animated)
let html = """
<a href="https://apps.apple.com/us/app/directorio-notarios-cdmx/id1544000342"> App store Deep link usually doesn't open </a></span></span><br />
<a href="https://landercorp.mx" rel="noopener"> Normal link </a></span></span><br />
"""
let webview = WKWebView()
webview.frame = view.bounds
webview.navigationDelegate = self
view.addSubview(webview)
webview.loadHTMLString(html, baseURL: nil)
}
// MARK: WKNavigationDelegates
func webView(_ webView: WKWebView,
decidePolicyFor navigationAction: WKNavigationAction,
decisionHandler: @escaping (WKNavigationActionPolicy) -> Void)
{
decisionHandler(.allow)
}
func webView(_ webView: WKWebView,
didFailProvisionalNavigation navigation: WKNavigation!,
withError error: Error)
{
manageFailedNavigation(webView,
didFail: navigation,
withError: error)
}
func webView(_ webView: WKWebView,
didFail navigation: WKNavigation!,
withError error: Error)
{
manageFailedNavigation(webView,
didFail: navigation,
withError: error)
}
private func manageFailedNavigation(_ webView: WKWebView,
didFail navigation: WKNavigation!,
withError error: Error)
{
// Check if this failed because of mailto, _blank, deep links etc
// I have commented out how to check for a specific case like open in a new tab,
// you can try to handle each case as you wish
if error.localizedDescription
== "Redirection to URL with a scheme that is not HTTP(S)"
//let url = webView.url, url.description.lowercased().range(of: "blank") != nil
{
// Convert error to NSError so we can access the url
let nsError = error as NSError
// Get the url from the error
// This key could change in future iOS releases
if let failedURL = nsError.userInfo["NSErrorFailingURLKey"] as? URL
{
// Check if the action can be handled by iOS
if UIApplication.shared.canOpenURL(failedURL)
{
// Request iOS to open handle the link
UIApplication.shared.open(failedURL, options: [:],
completionHandler: nil)
}
}
}
}
}
This way, both cases are handled where the HTTPs url scheme is followed and not
