If you want to access the Twitter API from your iPhone app, you’re going to have to use OAuth. (Twitter is turning off Basic Authentication support at the end of June.) To use OAuth, you need to follow these basic steps:
- Get a request token from Twitter
- Send the user to Twitter (via Safari) to authorize the request token
- Exchange the request token for an access token
- Use the access token to interact with the user’s Twitter account
The sticky part comes between steps (2.) and (3.): How can you gracefully restart your application after the user has authorized the request token? The answer lies with Custom URL Schemes.
Setup
When you register an app with Twitter, you’re asked to supply several pieces of information. We’re interested in two of them:
- Application Type
- Callback URL
You might think, since you’re developing an iPhone app, that you’d want to select “Client” for “Application Type”. You don’t. You want to select “Browser”, so that Twitter will (ultimately) redirect the user back to your application, instead of sending him into a tedious PIN-based procedure.
As for “Callback URL”, set it to any webpage that you can script. For instance, you might set it to:
http://www.example.com/apps/iExample/oauth_handler.php
Script
The preceding Twitter configuration will send the user to your webpage after he authorizes a request token. (Or, for that matter, after he declines to authorize one.) Now you need to send him from that webpage back to your application. You can do this with a little redirect script (or even an Apache configuration directive, I suppose); the following example is written in PHP:
<?php
$key = $_GET['oauth_token'];
$url = "tweeter://restart";
if ($key)
{
$url .= "?oauth_token=" . $key;
}
else
{
$url .= "?no";
}
header("Location: " . $url);
?>
Custom URL Scheme
That script will redirect Safari to a URL with a custom “tweeter://” scheme; to make the iPhone/Safari pick up this scheme and start our app, we need to configure our app’s info.plist
file. Long story short, it should look something like this:
Startup
All the preceding configuration will cause Twitter to redirect a user to our custom webpage, that page to redirect him to a custom URL, and Safari to start our app with that URL as an argument. We just need to recode the app to check for this startup condition.
An application:didFinishLaunchingWithOptions:
method should be added to our app’s application delegate. Something like this:
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
// … snip …
// Handle a return from Twitter authorization.
NSString* query = [[launchOptions objectForKey:UIApplicationLaunchOptionsURLKey] query];
if (query)
{
// If there's a token in the query, use it to (attempt to) get an access token
NSRange range = [query rangeOfString:@"oauth_token="];
if (range.location != NSNotFound)
{
// Extract request key
NSString* request_key = [query substringFromIndex:range.location+range.length];
// Do something clever
// …
}
}
return YES;
}
In practice, there are other considerations — the startup URL only gives you the “key” half of the request token, so you need to marry it up to the “secret” half yourself, and you’ll also want to handle manual restarts after authorization (in addition to URL-driven ones) — but the preceding code is the heart of the matter.
Simplification?
You might ask some questions at this point:
- Couldn’t we set
oauth_callback
when fetching a request token, instead of setting “Callback URL” when registering the application? - Couldn’t we set “Callback URL” to a custom URL directly, and avoid the intermediate webpage?
To the first question: Sure, I guess. If that’s what you want to do, go ahead. It seems that less can go wrong if “Callback URL” is set, though.
To the second: I wouldn’t like to rely upon Twitter to faithfully perform redirects to non-standard URL schemes. Even if it works today, it might not work tomorrow (when some bright spark decides to “validate” URLs and “fix” “bogus” schemes). In principle, though, I guess it could work.