The scheme name (or protocol) of a URL is the first part of a URL - e.g. schemename://. For web pages, the scheme is usually http (or https). The iPhone supports these URL schemes:
http, https, ftp | Web links* (Safari) |
mailto | E-mail links (launches the Mail app) |
tel | Telephone Numbers (launches the phone app) |
sms | Text Messages (launches the SMS app) |
* Web links that point to http://maps.google.com are redirected to the Maps app.
* Web links that point to http://www.youtube.com are redirected to the YouTube app.
* iTunes store links (http://phobos.apple.com/etc..) are sent to the iTunes (or App store) app.
iPhone apps can also specify their own custom URL scheme (for example, myapp://doStuff). When might you want to use a custom URL scheme for your app?
- To transfer data from lite to paid versions of your app
- To allow other apps (or even web pages) to call your app (and send data to it)
- To handle callbacks for custom authentication (such as OAuth) and third party API's
Implementing a Custom URL Scheme
Defining your app's custom URL scheme is all done in the Info.plist file. Click on the last line in the file and then click the "+" sign off to the right to add a new line. Select URL Types for the new item. Once that's added, click the grey arrow next to "URL Types" to show "Item 0". Set your URL identifier to a unique string - something like com.yourcompany.yourappname.
After you've set the URL identifier, select that line and click the "+" sign again, and add a new item for URL Schemes. Then click the grey arrow next to "URL Schemes" to reveal "Item 0". Set the value for Item 0 to be your URL scheme name.
Handling Custom URL Calls
In order for your app to respond when it receives a custom URL call, you must implement the application:handleOpenURL method in the application delegate class:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { // handler code here }
Parsing the Custom URL
There are several parts to a URL:
scheme://host/path?query
The parts to the URL can be retrieved through the NSURL object that is passed into the application:handleOpenURL method. If you have a fairly simple URL naming scheme and want to allow access to specific pages/keys, you can just use the host name:
Custom URL | Value of [url host]: |
---|---|
myapp://page1 | page1 |
myapp://page2 | page2 |
myapp://otherPage | otherPage |
To pass data into your app, you'll want to use the query string. Here's a simple method for parsing the query string from the url:
- (NSDictionary *)parseQueryString:(NSString *)query { NSMutableDictionary *dict = [[[NSMutableDictionary alloc] initWithCapacity:6] autorelease]; NSArray *pairs = [query componentsSeparatedByString:@"&"]; for (NSString *pair in pairs) { NSArray *elements = [pair componentsSeparatedByString:@"="]; NSString *key = [[elements objectAtIndex:0] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSString *val = [[elements objectAtIndex:1] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; [dict setObject:val forKey:key]; } return dict; }
Testing The Custom URL
You can easily test your URL scheme in the simulator. Just add a test button to one of your views, and implement the IBAction method for it as follows:
- (IBAction)getTest:(id)sender { [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"myappscheme://test_page/one?token=12345&domain=foo.com"]]; }
Then in your app delegate, implement the application:handleOpenURL method:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { NSLog(@"url recieved: %@", url); NSLog(@"query string: %@", [url query]); NSLog(@"host: %@", [url host]); NSLog(@"url path: %@", [url path]); NSDictionary *dict = [self parseQueryString:[url query]]; NSLog(@"query dict: %@", dict); return YES; }
(You'll also need the parseQueryString method from above.)
Additional References
- Apple URL Scheme Reference
- NSURL Class Reference
- OAuthConsumer (OAuth library for Mac/iPhone)