Kian Cross
Kian Cross

Reputation: 1818

How can I force any links clicked within a WebView to open in Safari?

I have a WebView in my application and I would like any links clicked within the WebView to open in Safari (instead of the WebView itself).

I am developing the application in Swift.

What is the best method to do this?

Upvotes: 17

Views: 27493

Answers (5)

Tony Macaren
Tony Macaren

Reputation: 457

According to recommendations in apple docs

enter image description here

Also UIWebView is deprecated after 12 iOS

Here is solution using Swift 5.3 and WKWebiew

First replace your UIWebview with WKWebview

Then conform to WKNavigationDelegate and implement method

enter image description here

Here is code

extension WebViewControllerImpl: WKNavigationDelegate {
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        guard case .linkActivated = navigationAction.navigationType,
              let url = navigationAction.request.url
        else {
            decisionHandler(.allow)
            return
        }
        decisionHandler(.cancel)
        UIApplication.shared.openURL(url)
   }
}

Then set 'navigationDelegate' for your wkWebView

wkWebView.navigationDelegate = self

Upvotes: 8

Cesar Bielich
Cesar Bielich

Reputation: 4945

Updated for swift 4.2

func webView(_: UIWebView, shouldStartLoadWith: URLRequest, navigationType: UIWebView.NavigationType) -> Bool {
    if navigationType == UIWebView.NavigationType.linkClicked {
        UIApplication.shared.open(shouldStartLoadWith.url!, options: [:], completionHandler: nil)
        return false
    }
    return true
}

Upvotes: 1

Ronald Martin
Ronald Martin

Reputation: 4468

This is done essentially the same way in Swift as in Obj-C:

First, declare that your view controller conforms to UIWebViewDelegate

class MyViewController: UIWebViewDelegate

Then implement webViewShouldStartLoadingWithRequest:navigationType: in your View Controller:

// Swift 1 & 2
func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
    switch navigationType {
    case .LinkClicked:
        // Open links in Safari
        UIApplication.sharedApplication().openURL(request.URL)
        return false
    default:
        // Handle other navigation types...
        return true
    }
}

// Swift 3
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
    switch navigationType {
    case .linkClicked:
        // Open links in Safari
        guard let url = request.url else { return true }

        if #available(iOS 10.0, *) {
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
        } else {
            // openURL(_:) is deprecated in iOS 10+.
            UIApplication.shared.openURL(url)
        }
        return false
    default:
        // Handle other navigation types...
        return true
    }
}

Finally, set your UIWebView's delegate, e.g., in viewDidLoad or in your Storyboard:

webView.delegate = self

Upvotes: 48

Femi Loki
Femi Loki

Reputation: 81

Updated for swift 3

func webView(_: UIWebView, shouldStartLoadWith: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
    if navigationType == UIWebViewNavigationType.linkClicked {
        UIApplication.shared.open(shouldStartLoadWith.url!, options: [:], completionHandler: nil)
        return false
    }
    return true
}

Upvotes: 7

jefflovejapan
jefflovejapan

Reputation: 2121

You need to implement the method webViewShouldStartLoadingWithRequest:navigationType on your web view's delegate and look for the links you want to open in Safari. If you send those off to the OS with [[UIApplication sharedApplication]openURL:] they will open in Safari.

Upvotes: 3

Related Questions