iOS, Swift

Using OpenURL to launch links in a UIWebView

UIWebView in great for displaying HTML formatting information in your app.  In many cases you might be displaying fragments you didn’t create opening the door for links your user might action.  By default your embedded UIWebView will follow the link which can lead to an odd user experience.  There are several options for handling this including opening the SFSafariViewController.  Since a majority of text I will be displaying doesn’t have links I will just be using openURL to open the link in Safari. With the back button introduced in iOS9 this simplistic user experience can be added in just a few lines of code. The below walks through what is needed to implement this approach.

Adding the delegate

First the UIWebViewDelegate Protocol needs to be added to your controller.   This allows us to override the necessary loading content methods.

import UIKit

class ViewController: UIViewController, UIWebViewDelegate {

    @IBOutlet weak var webView: UIWebView!
    let html = "<div>Lorem ipsum dolor sit amet..."

}

Next in your viewDidLoad override method set the delegate method of your UIWebView to the controller, ie self.

override func viewDidLoad() {
    super.viewDidLoad()
    self.webView.delegate = self
    self.webView.loadHTMLString(html, baseURL: nil)
}

Loading Content

The final step is to add the webView:shouldStartLoadWithRequest:navigationType: method. This will be called whenever content is loaded or a navigation action such as clicking on a link is called.

func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {

    if navigationType == UIWebViewNavigationType.LinkClicked {
        UIApplication.sharedApplication().openURL(request.URL!)
        return false
    }
    
    return true
}

You will notice we are checking if the navigationType  is LinkClicked  and then using openURL to open the link in Safari.  It is important to note that if this is a link we return false. This will stop the UIWebView from loading the link content.  Otherwise we always return true so the HTML passed to the UIWebView will load as expected.

The Result

With our delegate and content loading method in place Safari will load each time the user taps on a link in your UIWebView.  The following shows this snippet in action.

UIWebViewOpenUrl

A gist with the complete code is available here.