iPhone Developer Tips Stats:
|
Launching Your Own Application via a Custom URL Scheme
One of the coolest features of the iPhone SDK is an application’s ability to “bind” itself to a custom URL scheme and for that scheme to be used to launch itself from either a browser or from another application on the iPhone. Creating this kind of binding is so simple, its almost criminal not to use it in your application!
Before you get started, you need to figure out how you want you application to respond to the URL. The simplest way to use custom schemes is to just “wake up”; but it is also possible to pass information to the application via the URL, and in so doing, enable the application to do different things when woken up.
Registering Custom URL Schemes
Regardless of what you want to do once your application is started, the first step is to register a custom URL scheme with the iPhone. This is done via the info.plist file located in your application’s project folder (NOTE: this is the same file you would change to define a custom icon).
By default, when opened, XCode will edit the file in a graphical UI. It is possible to edit the info.plist file directly in Text mode which may be easier for some people.
Step 1. Right-Click and “Add Row”

Step 2. Select “URL types” as the Key

Step 3. Expand “Item 1″ and provide a value for the URL identifier. This can be any value, but the convention is to use a “reverse domain name” (ex “com.myapp”).

Step 4. Add another row, this time to “Item 1″.

Step 5. Select “URL Schemes” as the Key.

Step 6. Enter the characters that will become your URL scheme (e.g. “myapp://” would be “myapp”). It is possible for more than one scheme to be registered by adding to this section though that would be strange thing to do.

NOTE: If you open the info.plist file in a text editor you will see the following has been added to the file …
CFBundleURLTypes
CFBundleURLSchemes
myapp
CFBundleURLName
com.yourcompany.myappOptionally Handle the URL
Now that the URL has been registered. Anyone can start the application by opening a URL using your scheme.
Here are a few examples …
myapp:// myapp://some/path/here myapp://?foo=1&bar=2 myapp://some/path/here?foo=1&bar=2
The iPhone SDK, when launching the application in response to any of the URLs above, will send a message to the UIApplicationDelegate.
If you want to provide a custom handler, simply provide an implementation for the message in your delegate. For example:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { // Do something with the url here }
A common technique is to parse the URL passed in and pull from it the parameters that will be used by various views in the application and store them in the User Preference. Below is an example where we store the URL as a value parameter “url” in just such a manner …
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { if (!url) { return NO; } NSString *URLString = [url absoluteString]; [[NSUserDefaults standardUserDefaults] setObject:URLString forKey:@"url"]; [[NSUserDefaults standardUserDefaults] synchronize]; return YES; }
Now you have everything you need to enable others to wake-up your application and even pass it information! Enjoy!









great! thx a ton for this…
but what happens incase of conflicts… more than 1 applications have same URL scheme ?
/V
How can we make the URL of application such that User can click on the email or in the sms and Our app can start??
Thanks in advance
I my be barking up the wrong tree.
I am wanting to add a url to my iPhone app that would launch safari, then load my website, when you tap on the url text in my app.
Thanks for any help you can offer.
Mark
@vibhor If there is already an application registered with that scheme then it will throw an exception when it first attempts to bind. Your questions is a good one however. I’m not sure how you “work-around” that issue.
@sanniv
You may want to check out:
http://iphonedevelopertips.com/cocoa/launching-other-apps-within-an-iphone-application.html
I love the idea of this, but Apple have managed to leave out custom scheme recognition from two of its core applications, MobileMail and SMS. Using any of these custom schemes here won’t work as these apps do not recognise the links.
@vibhor / @rodney
I’d like to follow up on vibhor’s comment. I have the same application “skinned” for different clients. I tried originally set up:
URL Identifier as com.client1, com.client2 etc and
URL schema as myapp
If I install different client apps to the same phone then the app which gets launched through the myapp:// URL is the most recent one installed.
Instead I changed the URL schema to myappclient1, myappclient2 etc which solves the immediate problem for my application(s) but it still does not resolve any conflicts introduced from other applications.
The URL identifier part of this setup seems redundant. Can anyone explain what it is used for?
Thanks…
HI…
Thanks for the great help…
But I am trying to use this to integrate my web application with iPhone app… I have put the URL directly on the html page and when user clicks on it is launches my native application. Now I am doing this successfully using the same technique given above.
But if the app is not installed on user’s phone then I wish to take him to the store to my app. So can anyone please tell me how can I work this out.
@Saurabh– You have to give 2 buttons in your html page and also ask user if they have app, press “Launch app” button and if they don’t then press, “Get App” button and in get app button call the itunes url of your app.
I think in this way you can take the users to store to your app.
Thanks for you help guys. I did get it worked out finally.
Q: Will this work from within the app? For instance, in a tab bar-based app with multiple Web Views, it would be nice to be able to pick a link within one web view, and immediately end up at application:handleOpenURL: since the app is already running. (If not, how is this sort of thing accomplished within an app that uses web views?)
MuiKit, my “random stuff” library, has a category for parsing query strings in URLs. See http://github.com/millenomi/muikit/blob/master/NSURL+L0URLParsing.h and http://github.com/millenomi/muikit/blob/master/NSURL+L0URLParsing.m for more.
We’re working on a centralized place to register all public URL schemes: http://www.handleOpenURL.com
Please add your URL schemes to the index: http://www.handleOpenURL.com/developers
The aim is to work towards a more elegant and advanced manner of sharing your apps functionality with other apps.
Thanks,
Q: can i use this tutorial to do a call from my app. without [[uiapplication sharedApplication]openURL:@”tel:1000000001″]?
Anyone figure out the answer to @Joe’s question above? Can you use these from within an app to message that same app without relaunching it?
@Aaron: Greetings! If application:handleOpenURL: is _not_ invoked, the next best thing might be to check the delegate method webView:shouldStartLoadWithRequest:navigationType: … though I’m hopeful it’s still possible the other way. :)
Regarding Joe’s question…
Create a class that implements the IWebViewDelegate protocol and implement the shouldStartLoadWithRequest method. When your webview needs to load a page (via a clicked link, an ajax request, some sort of javascript event, whatever…) it will call this method on your delegate and pass in an NSUrlRequest object.
if [[request url] scheme] is your app’s custom scheme, go ahead and do whatever it is the url indicates you should do, and return NO to prevent the webview from continuing to process the request. If the scheme isn’t something you want to catch, return YES to let the webview handle the request in the usual manner.
PhoneGap does this (see /iphone/PhoneGapLib/Classes/PhoneGapDelegate.m) in a very elegant way, providing a way for their javascript framework to call methods written in obj-c. They use the stringByEvaluatingJavaScriptFromString method of the webview to pass information back into the browser from obj-c, which is also pretty slick.
@brandon – right on! Thanks for walking through that. Very much appreciated.
I’ve written an app that hides the status bar at the top of the phone (the one with the carrier, etc.) When I open it using this method, the bar shows up. How can I keep it hidden?
What happens if the iPhone or iPod touch doesn’t have the app installed?
@Lawson Culver – this one had me bugged too. Instead of doing it through code ( [[UIApplication sharedApplication] setStatusBarHidden: YES]; ) you will need to add the “Status bar is initially hidden” line to your Info.plist and check the box. Once I did that, it worked for me!
This works in a surprising way for me. I can launch the application through safari, but none of the deleagate gets called, no action methods gets called, but the app does launch. Wat can be the problem???
I have 2 apps, myapp1 and myapp2. I have configured a tab in myapp1 to launch myapp2. I have created custom url schemes for each app, so that one could call the other and vice versa. I have tested launching myapp2:// from myapp1 (with http://) and that works. When I use myapp2:// it does not. Both apps are installed on the device using ADHOC profiles.
Question: Does this only work if at least one of the apps (e.g., myapp2) is installed via the app store? I cannot understand how one custom app would be able to know about another custom app. It doesn’t seem like creating a custom url scheme goes the distance.
Has anyone tried custom app to custom app use of the custom url schemes approach? Thanks,
Jack