New: iPhone/iPad development course in Belgium in August.

1 Mar 2010

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.

Add Your Comment

Spam Protection by WP-SpamFree

xAuthTwitterEngine library and demo

xAuthTwitterEngine is a library and demo that aims to simplify the process of adding Twitter xAuth authentication to your iPhone apps.

  1. Incredibly awesome. I’m going to bring this into Appcelerator Titanium ASAP. Thanks so much for this!

    Jeff Haynie
  2. Hey Jeff,

    Happy to hear it; Titanium rocks! :)

    Aral
  3. Guys – be warned – there is a crash bug contained in the -(void)exchangeAccessTokenForUsername method when using an “&” in the password on Twitter.

    It causes an NSRangeException.

    Although I didn’t use Aral’s solution, I have pretty much the same code in my method in @ChirpieApp and it crashes (as does Aral’s demo of xAuth)…. It appears to be the NSArray carrying the parameters causing the problem.

    Hopefully I or someone will find a fix soon! Working on it :-)

    Steve Reynolds
  4. Aral,

    Just downloaded your test app. I am currently using Matt Gemmel code without xAuth/. I created a “shell” Twitter app with key and secret, but it unclear what values should be entered in the Settings page. I set up Application type “Client”, default access “read/write”. Should I “check” the value for “Use Twitter for login”?

    Also what should be the values of Application Website and and Website? Other types of XAuth (mYSqpce, for exa,ple), use iPhone Schemas to callback the app. This one does not seem to work that way.

    The application Details lists these values:

    Request token URL
    http://twitter.com/oauth/request_token

    Access token URL
    http://twitter.com/oauth/access_token

    Authorize URL
    http://twitter.com/oauth/authorize

    Are these correct? I still get “Authentication Error, please check your username password and try again”. I am using the correct username / password that works with apps that do not use xAuth. Please advise.

    Marco Papa
  5. I forgot to read one and open the support ticket to activate xAuth. Let’s see if they approve the request.

    Marco Papa
  6. Once I got approved:

    sutorius, Mar 18 05:14 pm (PDT):
    Hi,

    Thanks for your interest in XAuth. Your application now has the ability to use XAuth, and you can read the documentation here: http://apiwiki.twitter.com/Twitter-REST-API-Method%3A-oauth-access_token-for-xAuth .

    Thanks,
    Brian

    —-

    EVERYTHING WORKED!!!! Frigging great job Aral.

    Marco Papa
  7. Tried to port the example in one of my project. Get an error about yail … any idea?

    Cesare
  8. Hi Aral -

    Have you tried your sample app recently? I keep getting:

    NSURLErrorDomain Code=-1012 UserInfo=0×5201080 “Operation could not be completed. (NSURLErrorDomain error -1012.)”

    The Twitter API guys assure me everything is correct on their side and I’m positive my login information is correct. Just thought I’d mention it in case someone else was having the same problem.

    Thanks for your time,

    Christoph

    Christoph
  9. This is exactly what I was looking for! However, I can’t get it to work with my project. I am getting loads of errors, mostly based around: “yajl/yajl_parse.h: No such file or directory”

    I have added the libxml2 framework and added following to my Header Search Path: $SDKROOT/usr/include/libxml2

    Any idea what’s going on?

    Keller
  10. Yay! Turns out the Twitter API guys needed to reset my application. XAuthTwitterEngine is working like a champ now. Thanks Aral!

    Christoph
  11. Awesome combination of oauth and MGTwitter! However, I am recieving the same error as Keller. ” error: yajl/yajl_parse.h: No such file or directory” when brought into another project. Although your project compiles fine. Confused because I don’t see any yajl static libraries in your project. Is there an important aspect of xCode that I am missing?

    Any ideas greatly appreciated.

    Nate Potter
  12. Regarding the yajl compile errors others mentioned in their comments, take a look at the sample XCode project Targets->XAuthTwitterEngineDemo->Compile Sources. Note how not all the MGTwitter source files are included.

    So, you can’t do a simple drag and drop and include all the source code into your own project. If you don’t have the yajl source, you need to omit the yajl related parsing source code files in the MGTwitter library.

    Cheers,
    Brian

    Brian Stormont
  13. hi aral.
    I will using your xAuthTwitterEngine.
    but error “NSURLErrorDomain error -1012″.
    how to edit?

    luckymanjun
  14. Hi Aral,

    Just wanted to say thanks for this. You are a life saver.

    One question though. I need to show the user which Twitter account he is currently “connected with”.

    Once authentication is done is there a way to retrieve the account username that you know of?

    Michael Kaye
  15. wow! it worked so easily! thumbs up!

    nico
  16. Hello,
    I have been playing with your xAuth code, which saved me alot of effort. (ie, avoiding needing to figure out how to implement oauth myself :)

    In any case I had a suggestion for a patch. In the class: ExchangeCredentialsOperation.m

    When the class callbacks into the delegate, I suggest it should first check to see if the operation has been cancelled with [self isCancelled], and not call the callbacks if it has been cancelled.

    Brian
  17. Thanks Aral, this code was very useful. We were planning on twitter updates in our app Rhythmic and this made it so easy. For some reason I did get errors in the new beta xcode, but on the release version it seems to be fine…

    Prasanth
  18. I recompiled with the latest released XCode 3.2.2. Getting the token works, but sending the Tweet returns an error: “Twitter error! – 403 Operation could not be completed (HTTP error 403.)”

    This is what shows up on the console:

    2010-05-15 12:05:49.062 XAuthTwitterEngineDemo[2278:207] Access token string returned: oauth_token=15595897-56w43oUboH7Rn039mFm2Ekfoi70kOXgoXZ8miGwpc&oauth_token_secret=4XWA9ZofZBzlx7A9ToXmKvc3MoPaGQ5uYeHi1B7xlwg&user_id=15595897&screen_name=marcopapa&x_auth_expires=0

    2010-05-15 12:05:59.570 XAuthTwitterEngineDemo[2278:207] About to send test tweet: “Testing xAuth from the XAuthTwitterEngineDemo!”

    2010-05-15 12:05:59.571 XAuthTwitterEngineDemo[2278:207] About to carry out request with access token:

    2010-05-15 12:06:00.331 XAuthTwitterEngineDemo[2278:207] Twitter request failed: 18C9AA7E-05BF-408D-A8CE-7480A2FAD4CB with error:Error Domain=HTTP Code=403 “Operation could not be completed. (HTTP error 403.)”

    Any ideas why posting is now broken?

    Marco Papa
  19. It looks like the Error 403 on posting a tweet is not due to a recompile. I had an old complied version, with a cached token on an iPhone that was working, and now it gives the 403 error when posting a tweet. Is it possible Twitter changed something on their end?

    Marco Papa
  20. I found the solution to the “403 Operation could not be completed “. Twitter has instituted a process that rejects “duplicate” posts. So XAuthTwitterEngine Demo will succeed just once.You’ll need to change the message to post successfully again.

    Marco Papa
  21. Hi Aral,

    I am also getting the error NSURLErrorDomain Code=-1012 UserInfo=0×5201080 “Operation could not be completed. (NSURLErrorDomain error -1012.)”

    Any idea what that is or how to fix it?

    Ryan
  22. Hey Aral! I have a normal view, and upon pressing “post” it checks if there’s a token, if yes it should post, if no, then it slides up a login view. The problem is that, the login view detects the cached token (when I login), but the first view never does, how do I make it so the token is universal across my app. I appreciate it soooo much!

    -Vicc

    Victor Alexander
  23. I am getting the yajl/yajl_parse.h error.

    Is there any fix documented or is it just staring me straight in the face?

    Thanks for xAuthTwitterEngine!

    Sebastien Peek
  24. Guys – the yajl/yajl_parse.h error is confusing and the reason the demo works is that the files that need yajl are excluded from building, even though they’re in the project. To fix in your own project go into the MGTwitter folder via xcode and select each .m file with the term yajl in it (there should be 6), right-click -> Get Info -> Targets tab and uncheck the box next to your app name. HTH, Jon

    Jon
  25. Hi,

    The XAuthTwitterEngineDemo just does not seem to work for me.

    I always get:
    2010-06-19 14:01:38.670 XAuthTwitterEngineDemo[63945:4e53] access token did fail ***************
    2010-06-19 14:01:38.671 XAuthTwitterEngineDemo[63945:207] Error: Error Domain=NSURLErrorDomain Code=-1012 UserInfo=0×4b4a290 “Operation could not be completed. (NSURLErrorDomain error -1012.)”

    I entered my consumer key and secret correctly and Twitter say that they have approved XAuth for my app, so I am out of ideas.

    Could you help?

    Thanks
    J

    JS
  26. Hi Aral,

    Sorry, please ignore my last comment. I got it working.

    I’m extremely embarrassed to say that somehow my consumer secret had been munged. By replacing it, everything worked.

    Thanks for a great framework!

    Cheers
    J

    JS
  27. Hi Aral,

    Thank you very much for this tutorial. I tried your codes but I seem to get a Error: Error Domain=NSURLErrorDomain Code=-1012 UserInfo=0×193640 “Operation could not be completed. (NSURLErrorDomain error -1012.)”.

    Even after registering my app with Twitter. Any idea why?

    Ram
  28. [...] iPhone xAuth Explained with Sample Code [...]

    Search 4 Twitter xAuth and OAuth Samples ENDS here « iPhone Development
  29. For yajl compile error.

    Thanks to JON.

    It works.

    Hwang
  30. Hello… What kind of verifications should be made to check if the user revoked the token on twitter side.
    On my tests, when I revoke the access from the app on twitter, if I have a stored token on keychain, isAuthenticaded always answers true, even if it is not…

    marsson