xAuthTwitterEngine library and demo - deprecated

Update: November 2, 2010: MGTwitterEngine now has oAuth and xAuth support so I'm deprecating XAuthTwitterEngine. In other words, don't use XAuthTwitterEngine for your new projects, use MGTwitterEngine instead. I've released an MGTwitterEngine demo project for iPhone based on the XAuthTwitterEngine demo to show you how to use MGTwitterEngine.

Historical info:

XAuthTwitterEngineDemo app I just released an open source library and a sample application to make it easy for you to implement Twitter's new browserless xAuth authentication mechanism in your iPhone apps. You can download the source code or fork it from the XAuthTwitterEngine repository on Github.

Twitter started rolling out access to its new xAuth beta to developers over the weekend. As you may know, I'm a big fan of xAuth for mobile and desktop applications and as such I began implementing xAuth in Feathers right away.

In the meanwhile, however, I found that the process was more convoluted than it needed to be, and, adapting an existing oAuth framework for xAuth brought along with it a lot of oAuth browser-based authentication bloat that you simply do not need to do xAuth.

So, I decided to bite the bullet and build a slimmed-down XAuth-only library called xAuthTwitterEngine based on the Twitter-oAuth-iPhone library by Ben Gottlieb et. al. (so many people have worked on this; check out the Acknowledgements, below, and the readme file in the source.)

Source and downloads

You can find the source code and download packages for the xAuthTwitterEngine library and demo in the XAuthTwitterEngine Github repository.

Note: The XAuthTwitterEngine is currently being updated rather frequently. Please make sure you check the repository and pull the latest version on a regular basis.

Usage: Overview

  1. If you haven't done so already, register your app with Twitter and ask for xAuth to be activated on your account by opening a support ticket. Make sure that you include the App ID of your app in your support ticket. The App ID is the number at the end of the URL on your app's Twitter page (e.g., http://twitter.com/oauth_clients/details/your_app_id).
  2. Open the XAuthTwitterEngineDemo XCode Project and add your Consumer Key and Consumer Secret into the constants at the top of XAuthTwitterEngineDemoViewController.h
  3. Run the app to test it out and look at the source to see how XAuthTwitterEngine works. Everything should be self-explanatory.
  4. Drag the Twitter+oAuth group under Libraries into your own project to add XAuthTwitterEngine to your project. Don't forget to add the libxml2.dylib framework to your project too.

The important bits of the code in the demo are highlighted, below.

Setting up an XAuthTwitterEngine instance

//
// Initialize the XAuthTwitterEngine.
//
self.twitterEngine = [[XAuthTwitterEngine alloc] initXAuthWithDelegate:self];
self.twitterEngine.consumerKey = kOAuthConsumerKey;
self.twitterEngine.consumerSecret = kOAuthConsumerSecret;

if ([self.twitterEngine isAuthorized])
{
  UIAlertViewQuick(@"Cached xAuth token found!", @"This app was previously authorized for a Twitter account so you can press the second button to send a tweet now.", @"OK");
  self.sendTweetButton.enabled = YES;
}

Here, you instantiate the an XAuthTwitterEngine instance with the View Controller as its delegate (XAuthTwitterEngineDelegate). Note that the View Controller also implements methods from MGTwitterEngineDelegate.

Exchanging a username/password pair for an xAuth Access Token

This happens when the first button is tapped:

NSString *username = self.usernameTextField.text;
NSString *password = self.passwordTextField.text;
[self.twitterEngine exchangeAccessTokenForUsername:username password:password];

If an access token is successfully retrieved, the storeCachedTwitterXAuthAccessTokenString: forUsername: XAuthTwitterEngineDelegate method will get called with the tokenString and the username as arguments. In this method, save the tokenString to the keychain so you don't need to authenticate every time the app is run. (In the demo, it gets saved to NSUserDefaults to keep the demo simple – don't do this in real apps as it's not secure. Check out SFHFKeychainUtils if you want a simple way to store and retrive data from the keychain.)

Once you have the xAuth token, you should discard the user's username and password as they are no longer necessary.

If user authentication fails at this point, the twitterXAuthConnectionDidFailWithError: error: XAuthTwitterEngineDelegate method will get called instead.

Making a request

Once you have the xAuth access token, you can simply use the XAuthTwitterEngine like MGTwitterEngine (since it's basically Isaiah's oAuth-aware version of the MGTwitterEngine library.)

So, in the demo, here's how we send a tweet:

[self.twitterEngine sendUpdate:tweetText];

The requestSucceeded:connectionIdentifier: or requestFailed:error: MGTwitterEngineDelegate methods will get called as normally based on the outcome of the call.

Using cached tokens

Since you don't want to the user to have to authenticate every time, you should store the returned token string in the keychain and use that in future sessions. There are two ways you can use a cached token string: either by implementing the cachedTwitterXAuthAccessTokenStringForUsername: XAuthTwitterEngineDelegate method or by setting it directly on the XAuthTwitterEngine instance using the setAccessTokenFromTokenString: method.

The delegate method gets called automatically if you try to make a Twitter request using XAuthTwitterEngine without setting an access token first, so implementing the delegate method is a good way of passively ensuring that the engine will always use the cached token, if there is one.

For Twitter apps with multiple accounts (or if when the user wants to change the account in apps with a single account), you will want to update the access token manually within the session. For this, use the setAccessTokenFromTokenString: accessor method mentioned above.

Go forth and xAuth!

Now that Twitter has begun to support the xAuth flavor of oAuth for mobile and desktop apps, there is absolutely no reason for you not to implement it in your apps. Implementing xAuth means that your apps can take advantage of the organic marketing provided by the source parameter (the "via My App" bit at the bottom of tweets) and it means that users can revoke access to your application if they want to (for example, if your phone is stolen.)

xAuth won't stop malicious mobile/desktop apps from phishing user's details and neither is your application's identity any safer (since the consumer secret and consumer key are embedded in your app, ripe for reverse engineering) but these issues were not be addressed by browser-based oAuth either – not for mobile and desktop apps in any case.

I applaud Twitter once again for their pragmatism in creating xAuth. The next update of Feathers, which I hope to submit to Apple this week, will have xAuth implemented so you should start to see "via Feathers for iPhone" tweets start popping up on your timelines (in fact, if you follow me, you already have!)

I hope you enjoy XAuthTwitterEngine and that it saves you some time in getting up and running with xAuth.

Acknowledgements

Ben Gottlieb's effort was already based on a number of excellent components by Matt Gemmell, Jon Crosby, Chris Kimpton, and Isaiah Carew.

My xAuth version wouldn't have been possible this quickly without Steve Reynolds (author of the new Chirpie Twitter app for iPhone) who pointed me towards this xAuth implementationNorio Nomura.

For full credits, please see the readme file in the source.

Comments