iOS Custom URL Scheme

Today we are going to learn about custom URL schemes. I will write a tutorial in Swift, since I know lot of existing developers are now pro-Swift. But this code was written recently and things haven't changed much as long as Swift to Objective-C conversion goes.

Browser to app transition through custom URL schemes

This section will demonstrate how navigating an URL from a Apple Safari browser will redirect users to your app. You can even pass parameters to URL thus customizing user experience. First off you will have to add URL types in the project's info section,

  1. Click on your project file
  2. Navigate to info tag
  3. Expand section titled as URL types
  4. Click + button to add new URL type
  5. As an identifier you can add the name of your bundle id
  6. For URL schemes you can add the text relevant to your project function. Make sure you put all small caps and it is single word pertaining to your app
    for e.g. the URL scheme I put into my sample app is swiftexamples

This is what it will look like,

imageedit_3_9811054706

Now you can open a Safari browser and type

[URL_scheme]:// 

and verify that it opens your app. (In my case, I will simply type swiftexamples:// in the Safari navigation bar)

Adding parameters and unboxing them in the app


func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {

}

Here is the full code how this values can be extracted and logged on the console.

  1. Say you pass following link in the Safari,

[URL_scheme]://red

Now, the value red can be extracted as follows,


func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
        let urlScheme = url.scheme //[URL_scheme]
        let host = url.host //red
}
 
  1. You can even pass parameters to your app. For e.g. you can type,

[URL_scheme]://?backgroundColor=red

where backgroundColor = red is the parameter passed through the URL. You can unbox this parameters in following method in the AppDelegate


func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject) -> Bool {
        let urlComponents = NSURLComponents(URL: url, resolvingAgainstBaseURL: false)
        let items = (urlComponents?.queryItems)! as [NSURLQueryItem] // {name = backgroundcolor, value = red}
        if (url.scheme == "swiftexamples") {
            var color: UIColor? = nil
            var vcTitle = ""
            if let _ = items.first, propertyName = items.first?.name, propertyValue = items.first?.value {
                vcTitle = propertyName
                if (propertyValue == "red") {
                    color = UIColor.redColor()
                } else if (propertyValue == "green") {
                    color = UIColor.greenColor()
                }
            }
            
            if (color != nil) {
                let vc = UIViewController()
                vc.view.backgroundColor = color
                vc.title = vcTitle
                let navController = UINavigationController(rootViewController: vc)
                let barButtonItem = UIBarButtonItem(barButtonSystemItem: .Done, target: self, action: #selector(dismiss))
                vc.navigationItem.leftBarButtonItem = barButtonItem
                self.window?.rootViewController?.presentViewController(navController, animated: true, completion: nil)
                return true
            }
        }
        // URL Scheme entered through URL example : swiftexamples://red
        //swiftexamples://?backgroundColor=red
        return false
    }

Now you know how to perform custom URL schemes and open app through browser interface.

Here is the demo of how it looks like when you pass different parameter and app changes appearance based on the parameters passed.

Custom URL schemes demo

  • You can even take advantage of URL scheme to open one app from another one. For e.g. say you have to open an app belonging to scheme swiftexamples from another one. You can add button action and following code to verify for valid URL

- (IBAction)openCustomURLSchemeAction:(id)sender {
    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"swiftexamples://"]]) {
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"swiftexamples://?backgroundcolor=red"]];
    } else {
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://www.google.com"]];
        NSLog(@"Can't open url to show projects related to Swift examples");
    }
}

You can find the full source code with example on the Github

Make sure to use method canOpenURL on Appdelegate to check if app with that URL scheme exists. If you have more than one apps, you can use this method to bind them

I strongly recommend to go through a This article which explains pitfalls in querying custom URL schemes through canOpenURL