SFSafariViewController crash: The specified URL has an unsupported scheme

Sahil Kapoor picture Sahil Kapoor · Sep 30, 2015 · Viewed 14.2k times · Source

My code:

if let url = NSURL(string: "www.google.com") {
    let safariViewController = SFSafariViewController(URL: url)
    safariViewController.view.tintColor = UIColor.primaryOrangeColor()
    presentViewController(safariViewController, animated: true, completion: nil)
}

This crashes on initialization only with exception:

The specified URL has an unsupported scheme. Only HTTP and HTTPS URLs are supported

When I use url = NSURL(string: "http://www.google.com"), everything is fine. I am actually loading URL's from API and hence, I can't be sure that they will be prefixed with http(s)://.

How to tackle this problem? Should I check and prefix http:// always, or there's a workaround?

Answer

alanhchoi picture alanhchoi · Feb 17, 2016

Try checking scheme of URL before making an instance of SFSafariViewController.

Swift 3:

func openURL(_ urlString: String) {
    guard let url = URL(string: urlString) else {
        // not a valid URL
        return
    }

    if ["http", "https"].contains(url.scheme?.lowercased() ?? "") {
        // Can open with SFSafariViewController
        let safariViewController = SFSafariViewController(url: url)
        self.present(safariViewController, animated: true, completion: nil)
    } else {
        // Scheme is not supported or no scheme is given, use openURL
        UIApplication.shared.open(url, options: [:], completionHandler: nil)
    }
}

Swift 2:

func openURL(urlString: String) {
    guard let url = NSURL(string: urlString) else {
        // not a valid URL
        return
    }

    if ["http", "https"].contains(url.scheme.lowercaseString) {
        // Can open with SFSafariViewController
        let safariViewController = SFSafariViewController(URL: url)
        presentViewController(safariViewController, animated: true, completion: nil)
    } else {
        // Scheme is not supported or no scheme is given, use openURL
        UIApplication.sharedApplication().openURL(url)
    }
}