Dealing with the Twitter Oauth-Apocalypse

September 16th, 2010 Posted by: Collin - posted under:Tutorials

As many of you may have seen in recent weeks, Twitter changed its access policies and now that access Twitter user accounts. This is a large change from how many iPhone developers having been incorporating Twitter into their applications. What is OAuth exactly? How can iPhone developers get their apps up to date so they don’t break their Twitter incorporation? Well we have all the info you need to know about the OAuth-Apocalypse.

What is Oauth?

Twitter has a brief explanation of the difference between Basic Authentication and OAuth. They use the example of a letter and how it is addressed as their metaphor, and I think this gets the idea across clearly. You can see their entire explanation along with pros and cons .

TL;DR With Basic Auth you would make every request and would include a username and password with each. This method is very insecure because it allows applications to actively hold user’s credentials and does not have any accountability for which application is performing what action on who’s account. If you imagine your Twitter account as a room, this is like having access to the room be granted based on a single key that many people have copies of. OAuth makes access to your room be granted by a key pad. And everyone that has access to the room has a different code they input into the keypad. You can see who came in and when and revoke anyone’s code at any time.

Twitter is evolving and now requiring that applications register. As a result, user’s gain more control over what services have access to their account. Additionally, Twitter can be more effective at targeting malicious applications, and developers can get more accurate feedback on the frequency of their app’s use throughout Twitter. With all this said, OAuth is tough to implement from scratch. So today we are going to go through the installation and use of a collection of classes that takes care of the dirty work for us, and let developers update the Twitter functionality of their application easily.

Required Classes

Today we are going to be building off a collection of classes that were created by several different people. The main portion of the class is the MGTwitterEngine which was created by Matt Legend Gemmell who’s website can be found . From here, Ben Gottlieb took the classes and added his own drop in view controller to them. With all this together we have a simple view controller that will perform login and OAuth, and from there an engine that will perform any type of Twitter request we are looking to do. You can get a zip file of the root folder that contains all of these files here.

Installation

We are going to start out with a blank, view based iPhone project called iCodeOAuth. Once the project has come up, take the folder you downloaded called “Twitter+OAuth” and drag it into the “Other Sources” folder within Xcode. Make sure you check the box to copy the sources into the project folder. If we do a build now, you will get a ton of errors. That is because these classes require that libXML be a target of the project build as well. This can be accomplished by clicking the arrow next to Targets in the left column of the Xcode project. Here there will be an application called iCodeOAuth. If we right click on this and select Get Info we will see the info about our target. From here we click the build tab and search for the field “Header Search Paths”. You need to add the following into the Header Search Paths:

$(SDKROOT)/usr/include/libxml2

EDIT: I forgot to include here that you must also include a special XML library for the build to be successful. The Framework is called libxml2.dylib. You can find it at

/Macintosh HD/Developer/Platforms/iPhoneOS.platform/Developer/SDK/iPhoneOS4.1SDK/usr/lib

If you build again, you should see no errors and we can move forward with using this awesome set of classes.

Getting your Creds from Twitter

Now that we have these classes properly installed, it is time to take care of some registration requirements for OAuth. In order to use OAuth you must identify your app to Twitter. Once you do so, Twitter will provide you with an OAuthConsumerKey and an OAuthConsumerSecretKey. These are going to need to be provided to the classes we have just added into our project in order to talk with Twitter’s OAuth system. To register your application and get these creds go to . I have created a application called the iCodeBlog OAuth Demo, whose credentials are included in the sample app which I have provided. For your own personal app you will need to go create your own Twitter Application and get your own keys.

Using SA_OAuthTwitter Engine

Ben Gottlieb used a great design pattern to create a very easy to use access point for the more complex MGTwitterEngine which lies underneath. In order to use these classes we will go into out view controller and add the following code to the header:

#import "SA_OAuthTwitterEngine.h"
#import "SA_OAuthTwitterController.h"
 
@interface iCodeOauthViewController : UIViewController  {
 
        IBOutlet UITableView *tableView;
        IBOutlet UITextField *textfield;
 
        SA_OAuthTwitterEngine *_engine;
        NSMutableArray *tweets;
}
 
@property (nonatomic, retain) IBOutlet UITableView *tableView;
@property (nonatomic, retain) IBOutlet UITextField *textfield;
 
-(IBAction)updateStream:(id)sender;
-(IBAction)tweet:(id)sender;
 
@end

And add the following into the Main

- (void)viewDidAppear:(BOOL)animated {
 
        if(_engine) return;
 
        _engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate:self];
        _engine.consumerKey = @"PzkZj9g57ah2bcB58mD4Q";
        _engine.consumerSecret = @"OvogWpara8xybjMUDGcLklOeZSF12xnYHLE37rel2g";
 
        UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine: _engine delegate: self];
 
        if (controller)
                [self presentModalViewController: controller animated: YES];
        else {
                tweets = [[NSMutableArray alloc] init];
                [self updateStream:nil];
        }
}

This will instantiate our engine with the appropriate consumer and consumer secret keys. With this done we will create a controller. If you run the app now you will see a modal web view come up and lead to a sign in page for Twitter. This is a web view, but the great classes written by Ben are set up to programmatically handle the progression of these web views as the user signs in.

Scrolling to the bottom of this page there will be a username and password field to fill out. Don’t put in your Twitter credentials yet. We need to fill out a few delegate methods to handle the callback from SA_OAuthTwitterEngine.

Handling Login Callbacks

Insert the following into your main class.

 
-(IBAction)updateStream:(id)sender {
 
}
 
-(IBAction)tweet:(id)sender {
 
}
 
#pragma mark SA_OAuthTwitterEngineDelegate
 
- (void) storeCachedTwitterOAuthData: (NSString *) data forUsername: (NSString *) username {
 
        NSUserDefaults     *defaults = [NSUserDefaults standardUserDefaults];
 
        [defaults setObject: data forKey: @"authData"];
        [defaults synchronize];
}
 
- (NSString *) cachedTwitterOAuthDataForUsername: (NSString *) username {
 
        return [[NSUserDefaults standardUserDefaults] objectForKey: @"authData"];
}
 
#pragma mark SA_OAuthTwitterController Delegate
 
- (void) OAuthTwitterController: (SA_OAuthTwitterController *) controller authenticatedWithUsername: (NSString *) username {
 
        NSLog(@"Authenticated with user %@", username);
 
        tweets = [[NSMutableArray alloc] init];
        [self updateStream:nil];
}
 
- (void) OAuthTwitterControllerFailed: (SA_OAuthTwitterController *) controller {
 
        NSLog(@"Authentication Failure");
}
 
- (void) OAuthTwitterControllerCanceled: (SA_OAuthTwitterController *) controller {
 
        NSLog(@"Authentication Canceled");
}

We just implemented the SA_OAuthTwitterControllerDelegate and the SA_OAuthTwitterEngineDelegate. The SA_OAuthTwitterEngineDelegate methods take care of storing the OAuth data string in a plist so that when the app is launched again the user will not have to sign in. SA_OAuthTwitterControllerDelegate methods are callbacks depending on what happens upon sign in. In this case when sign in is successful another method in our class called updateTweets will fire. For now we have those methods defined but we don’t have them filled in. We will get to that in a few steps. If you run the application and login using some Twitter credentials, you should see a successful authentication message appear in your debug screen. With this done, let’s add some interface elements to our view controller XIB so that we can start interacting with Twitter. Our final product is going to look like this:

Building the Interface

To Build the interface open up the XIB for your view controller. We are going to be putting in 2 buttons, a UITextField and a UITableView. Lay the elements out like so.

Make sure to connect the delegate and data source of the table view to the file owner. Also connect the “Tweet This” button to the tweet method and the Update Tweets method to the updateStream method. Finally, make sure the IBOutlets for the UITextField and the UITableView are set. With these in place we can fill in the final methods to take advantage of our Twitter engine.

Filling in our IBActions

Put the following code in for the IBActions which we defied before.

#pragma mark IBActions
 
-(IBAction)updateStream:(id)sender {
 
        [_engine getFollowedTimelineSinceID:1 startingAtPage:1 count:100];
}
 
-(IBAction)tweet:(id)sender {
 
        [textfield resignFirstResponder];
        [_engine sendUpdate:[textfield text]];
        [self updateStream:nil];
}

The update stream method will ask our engine to get the Twitter timeline of the people you follow. It will retrieve the first page of the first 100 tweets. There is a delegate method that fires off on this request completing that we will fill out in a moment. The tweet method dismisses the keyboard and then uses our engine to send an update. Once the update is send we update the tweet view below.

Making a really simple Tweet Object

To help us with displaying tweets we are going to make a very quick Tweet object. This will be a simple NSObject subclass. Use this code for the header:

@interface Tweet : NSObject {
 
        NSDictionary *contents;
}
 
-(NSString*)tweet;
-(NSString*)author;
 
@end

And this code for the main

@implementation Tweet
 
-(id)initWithTweetDictionary:(NSDictionary*)_contents {
 
        if(self = [super init]) {
 
                contents = _contents;
                [contents retain];
        }
 
        return self;
}
 
-(NSString*)tweet {
 
        return [contents objectForKey:@"text"];
}
 
-(NSString*)author {
 
        return [[contents objectForKey:@"user"] objectForKey:@"screen_name"];
}
@end

Finally make sure to import the class within the main of your view controller class. These will simply give easy methods to get the info we want out of each tweet dictionary that the MGTwitterEngine will return to us.

Filling in our MGTwitterEngineDelegate Methods

The MGTwitterEngine is doing most of the heavy lifting here when it comes to interacting with Twitter. The methods we are using to get tweets and to send tweets are all defined within the MGTwitterEngine. There is also a defined MGTwtterEngineDelegate which defines the callback methods that fire upon these requests finishing. For the sake of completeness, I have filled out all the methods, although only a few of them will be called in the case of our application working properly. Insert the following code into your main.

#pragma mark MGTwitterEngineDelegate Methods
 
- (void)requestSucceeded:(NSString *)connectionIdentifier {
 
        NSLog(@"Request Suceeded: %@", connectionIdentifier);
}
 
- (void)statusesReceived:(NSArray *)statuses forRequest:(NSString *)connectionIdentifier {
 
        tweets = [[NSMutableArray alloc] init];
 
        for(NSDictionary *d in statuses) {
 
                NSLog(@"See dictionary: %@", d);
 
                Tweet *tweet = [[Tweet alloc] initWithTweetDictionary:d];
                [tweets addObject:tweet];
                [tweet release];
        }
 
        [self.tableView reloadData];
}
 
- (void)receivedObject:(NSDictionary *)dictionary forRequest:(NSString *)connectionIdentifier {
 
        NSLog(@"Recieved Object: %@", dictionary);
}
 
- (void)directMessagesReceived:(NSArray *)messages forRequest:(NSString *)connectionIdentifier {
 
        NSLog(@"Direct Messages Received: %@", messages);
}
 
- (void)userInfoReceived:(NSArray *)userInfo forRequest:(NSString *)connectionIdentifier {
 
        NSLog(@"User Info Received: %@", userInfo);
}
 
- (void)miscInfoReceived:(NSArray *)miscInfo forRequest:(NSString *)connectionIdentifier {
 
        NSLog(@"Misc Info Received: %@", miscInfo);
}

These methods are all very straightforward in their naming. The only one we fill out significantly is the statusesReceived:forRequest method. Here is where tweets will be returned to us, each as a separate dictionary when we request the timeline for a user. We will clear the tweets array that we have defined for our class and create a Tweet object for each of the dictionaries we have representing a tweet. From there we will ask our table view to reload. The only task we have left to perform is to fill in our table view data source methods to show all the tweets.

Table View Data Source and Delegate Methods

Now we have everything in place. We just need to create a UITableViewCell for every tweet we have. We will also do some tweaking of the size of each cell and the number of lines of each UITextField within each table view cell. These methods are very common so I wont go into much detail on them. Here are the necessary Data Source and Delegate Methods.

#pragma mark UITableViewDataSource Methods
 
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
 
        return [tweets count];
}
 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
 
        NSString *identifier = @"cell";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
 
        if(!cell) {
 
                cell = [[UITableViewCell alloc] initWithStyle:UITableViewStyleGrouped reuseIdentifier:identifier];
                //[cell setBackgroundColor:[UIColor clearColor]];
        }
 
        [cell.textLabel setNumberOfLines:7];
        [cell.textLabel setText:[(Tweet*)[tweets objectAtIndex:indexPath.row] tweet]];
 
        return cell;
}
 
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
 
        return 150;
}

With this in place you will have an OAuth twitter client that is capable of doing any type of interaction with Twitter. You can find the source for the project here. Please post any questions you have and happy coding!

Follow me on Twitter at

  • http://blog.indieiphonedev.com/2010/09/03/mgtwitterengine-and-locations/ Twitter on iPhone and Location using MGTwitterEngine | Indie iPhone Development Blog

    [...] to get it running on the iPhone and working with OAuth.  Update:  The guys at iCodeBlog have a great tutorial on how to implement the [...]

  • bob

    Please have this article proofread! The level of writing errors is pretty embarrassing…

  • http://www.rightsprite.com Collin

    Thanks for pointing this out Bob. Cleaned up the article a bit. Enjoy.

  • http://icode.dreamvision-soft.com/blog/?p=84 Dealing with the Twitter Oauth-Apocalypse | iCode

    [...] Original post on iCodeBlog [...]

  • http://inspirosoftware.co.uk James

    Maybe add the user that tweeted the Tweet in the Table View?

    Many thanks :D :D

  • Gabriel

    Hi! When I first run the app after the coding of the first view controller, it opens the Twitter simulator and it tries to open the web page to request a token, but it does not open. It gives me the message “Sorry, that page doesn’t exist!”. What is the right page address and where do I put it? Thank You!

  • Muthu

    I also get the same error as Gabriel, Someone please respond!

    Thank you!!

  • http://www.ssselvan.com/?p=167 Sidambara Selvan Blog » Blog Archive » Dealing with the Twitter Oauth-Apocalypse

    [...] view to the file owner. Also connect the “Tweet This” button to the tweet method and the Update Tweets method to the updateStream method. Finally, make sure the IBOutlets for the UITextField and the [...]

  • http://crifei93.wordpress.com crifei

    Hi,
    really great tut: but i don’t understand what you mean with “Insert the following into your main class.

    675d573355a441e62613bde1b82804c5002″!
    Please help,
    P.S: keep the good work up.

  • pop

    After I add the $(SDKROOT)/usr/include/libxml2 to the search path, I still get errors.
    I have followed this over and over. When you first add Twitter+OAuth, you get 100s of errors. After adding the header search path, I still get 8 errors. Any ideas?
    thanks :)

  • http://maniacdev.com/2010/09/tutorial-simple-twitter-client-using-oauth-authentication/ Tutorial: Simple Twitter Client Using Oauth Authentication | iPhone, iOS 4, iPad SDK Development Tutorial and Programming Tips

    [...] The tutorial is from Collin Ruffenach and can be found here: Dealing With The Twitter Oauth Apocalypse [...]

  • Franco

    Anyway, its great stuff, thank you :)

  • http://www.shawnsbits.com Shawn Grimes

    Looks like we are missing a bit of the code in the tutorial.

    Under the heading “Handling Login Callbacks”, you have:
    “Insert the following into your main class.

    41fa2bc55dd63a55a349bfb855a2039f002

    We just implemented the SA_OAuthTwitterControllerDelegate”

    I think there should be code instead of the string of letters and digits??

  • http://www.rightsprite.com Collin

    Hey Shawn, sorry about that. Stupid WordPress. Fixed now.

  • http://www.rightsprite.com Collin

    Hey Pop, this is my fault. Forgot you need to include a special framework too. Instructions have been added in.

  • http://www.rightsprite.com Collin

    Hey Ceifei, this has been updated. Sorry for the confusion.

  • http://www.rightsprite.com Collin

    Gabriel and Muthu,

    I have not experienced this yet. Maybe Twitter was having issues. Try again.

  • http://www.shawnsbits.com Shawn Grimes

    Many thanks for the fix. Took me about 15 mintues and I had twitter integration working in my app. Thank you!

  • http://waynedahlberg.com Wayne Dahlberg

    Thank you very much for the updates, and for this tutorial.

  • Gabriel

    I’m still having the same error… I’ve downloaded your code but it is showing the message that the page doesn’t exist =(

  • http://horde.greendragonempire.com Petraeus Prime

    Works like a charm, thank you very much and keep the tutorials coming!

  • Alfredo

    Please help us! I am receiving the “Sorry, that page doesnt exist” page of Twitter too. I have tried multiple solutions and im still getting that page :(

  • Steve B

    Thanks for this article! You’ve helped me make my app so much better!!! One question though, how do I handle an update failing to post? I can’t seem to get that to work… Any help you can provide would be great!

  • ashokbabuy

    You really saved a lot of time for me. Thanks for the great tutorial.

  • louis

    hi,

    after installing the libxml2.dylib and adding the $(SDKROOT)/usr/include/libxml2 line I’m still having 140 errors :(
    The first one is : error: libxml/xmlreader.h: No such file or directory
    does that make sense?
    What should I do ?

    thanks
    Louis

  • louis

    never mind, I figured it out, thanks :)

  • Christoph

    I’m testing your example with my own consumerKey and consumerSecret, but it’s not working… what I have to change in my registration application?

  • Christoph

    actually, don’t tweet anything just update my timeline

  • suchita

    when i use my application consumerkey & consumersecret then its not provide pin code what i do for resolve it.

  • suchita

    I download ur app & run its work perfectly But when i used my consumerkey & consumersecret
    and run app its shows twitter environment i set username & password & then click button allow its shows SELECT AND COPY THE PIN for show my app as it is ur’s app what i do for it plz provide solution as soon as possible.
    thanx in advance…

  • Christoph

    try with your Application Type: ‘Client’

  • pop

    got it to work fine in the sim and on a 3g with 4.1. When I run it on and original iPhone with 3.1.3, it hangs when it tries to load the authentication page.

    Any ideas?

  • http://www.michaelrowe01.com Michael Rowe

    I am also seeing this. When I put in a site to find, it prompts me to log into Twitter instead of using the OAuth. Any suggestions>

  • Ron Cox

    I have a simple scenario for Twitter use: all I need to do is post a status update. Authorization works fine. But the update fails. What am I missing? Here’s the content of the error object:

    Error Domain=NSURLErrorDomain Code=-1200 “An SSL error has occurred and a secure connection to the server cannot be made.” UserInfo=0xfbde7d0 {NSErrorFailingURLStringKey=https://twitter.com/statuses/update.xml, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, NSErrorFailingURLKey=https://twitter.com/statuses/update.xml, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSUnderlyingError=0xfbde800 “An SSL error has occurred and a secure connection to the server cannot be made.”, NSURLErrorFailingURLPeerTrustErrorKey=}

  • Ron Cox

    UPDATE: I got it to work by adding this line:

    [_engine setUsesSecureConnection:NO];

    Is that line necessary? Shouldn’t it work with HTTPS?

  • lonestar790

    I hope someone can direct me. I can get the tutorial to work, but I am curious to know if there is a way to have the app log into an account with a user having the user info to make posts? I have a general wall posting that I like users of the app to be able to post at will, and I would like to store the authentication privately on the app. Thanks for the help.

  • lonestar790

    I have continued to read around, but no one directly answers the question- Can I embed the username and password into the app? I want users to have access to the account without giving out the info. If it is possible what is the best way to implement it with the Oauth? Thanks a ton.

  • http://www.michaelrowe01.com Michael Rowe

    Figured this one out.. was a network issue, and the code just loops until it gets a network.. no clean timeout. Thanks for the tutorial.

  • swati

    hey u helped me a lot
    thank u so much

  • Dan Grigsby

    Bob’s an ungrateful troll. Very useful tutorial.

  • Anthony S

    I have be searching high and low to find out if Oauth will allow some
    form of embedding the log-in info for a single account from the
    iphone. I was using the basic authorization, and with the change it is
    no longer working. I have a series of clients who post to an account
    to discuss their process for each project. I do not want to give them
    the log-in information, but I want them to have posting ability.

    I would prefer to embed the log-in token and just give one of the two
    authentication to them- either username or password (or neither). With
    Oauth can I use other peoples accounts to post to one. main account?

    I have read on the boards that everyone is skirting the issue, a
    twitter does not address it. Oauth appears to be the antithesis of
    this concept. Any help would be greatly appreciated.

    Just to be clear- I have a view that has a status box with a post
    button. Users with the app do not need to login (but need the app) to
    post to the account.) Now when I implement the Oauth, a log-in screen
    appears and request a username and password. This would give the users
    access to edit the account and to post. I don’t want them to be able
    to edit the account, but to just post to it.

    Thank you.

    A

  • lonestar790

    I LOVE your implimentation of the twitter feed. How do we add the access token from an account into this method? I want to hard code the info with the access token and the access token – secret. Thanks for the help.

  • http://thekinetik.com PRCode

    Thanks for the post bro!

  • http://www.michaelrowe01.com Michael Rowe

    Thanks for a great tutorial. I am looking to add twitter into my app and I am storing the USERID in the nsuserdefaults. I don’t want to store the password, but I also want to be able to prefill in the user ID, if the user needs to authenticate the app. I am not sure how just call the OAuth for Twitter using the attached example. Thanks in advance.

  • Isken

    This tutorial is great work on simulator(ios 4.1). But I run on iphone3g ios4.1 can not work. always request error 401. Somebody know this problem?

  • MTR

    I can able to compile and run the code in ios4 but when i compile in ios 3 its showing reference error can you please tell how to resolve this problem

  • http://www.michaelrowe01.com Michael Rowe

    OK, decided to not store UserID. Now I have something else weird happening. I went in and removed the app authorization from my Twitter account. I then toggled the switch on the app, and while the debugger showed it ran the code, the app never prompted to re-enable the authorization. any suggestions?

  • http://www.michaelrowe01.com Michael Rowe

    Btw, I tend to want to compile code with 0 warnings. I am seeing the following warnings when using this code -
    1) …/Classes/MeetingStartedViewController.m:484: warning: class ‘MeetingStartedViewController’ does not implement the ‘SA_OAuthTwitterControllerDelegate’ protocol
    2) …/Classes/MeetingStartedViewController.m:680: warning: no ‘-initWithTweetDictionary:’ method found
    3) …/Classes/MeetingStartedViewController.m:718: warning: local declaration of ‘tableView’ hides instance variable
    4) …/Twitter+OAuth/MGTwitterEngine/MGTwitterMessagesParser.m:45: warning: ‘MGTwitterStatusesParser’ may not respond to ‘-parser:didEndElement:namespaceURI:qualifiedName:’
    5) …/Twitter+OAuth/MGTwitterEngine/MGTwitterMiscParser.m:39: warning: ‘MGTwitterStatusesParser’ may not respond to ‘-parser:didEndElement:namespaceURI:qualifiedName:’
    6) …/Twitter+OAuth/MGTwitterEngine/MGTwitterStatusesParser.m:55: warning: ‘MGTwitterXMLParser’ may not respond to ‘-parser:didEndElement:namespaceURI:qualifiedName:’
    7) …/Twitter+OAuth/MGTwitterEngine/MGTwitterUsersParser.m:45: warning: ‘MGTwitterStatusesParser’ may not respond to ‘-parser:didEndElement:namespaceURI:qualifiedName:’ 8) …/Twitter+OAuth/MGTwitterEngine/MGTwitterXMLParser.m:45: warning: class ‘MGTwitterXMLParser’ does not implement the ‘NSXMLParserDelegate’ protocol

    Could these be causing my issue I describe above? Is anyone else seeing these warnings? If so, how did you fix them?

  • http://www.michaelrowe01.com Michael Rowe

    It appears that I am getting a NULL value from the call to UIViewController, since the if statement if (controller) is always executing the Else… Any suggestions?
    Here’s the code:

    - (IBAction)toggleTwitter:(id)sender{
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];

    // let’s set up Twitter authorization if the Switch is set to on
    if (twitterSwitch.on) {
    // first let’s store the value
    [prefs setInteger:1 forKey:@"keyTwitterSwitch"];
    // if(_engine) return; // If this is in, then the program only checked Engine once and I need it anytime the switch is toggled
    _engine = [[SA_OAuthTwitterEngine alloc] initOAuthWithDelegate:self];
    _engine.consumerKey = @”MYKEYREPLACED”;
    _engine.consumerSecret = @”MYSECRETREPLACED”;

    UIViewController *controller = [SA_OAuthTwitterController controllerToEnterCredentialsWithTwitterEngine: _engine delegate: self];

    if (controller)
    [self presentModalViewController: controller animated: YES];
    else {
    tweets = [[NSMutableArray alloc] init];
    [self updateStream:nil];
    }
    } else {
    [prefs setInteger:0 forKey:@"keyTwitterSwitch"];
    }
    [ [NSUserDefaults standardUserDefaults] synchronize];
    [sender resignFirstResponder];
    }

  • hib

    If we want to give logout how can we deal with it ?

  • Stanley Wu

    this tut is working like a charm, I got it to work and managed to display user name and the tweet they posted to load in the tableview.
    however, I am stuck with a few problems, first with an easy one:how do I display the profile image of the user to load in the cell??
    secondly, I want my app to display the full message and user info when I click a specific cell, how do I do that??
    sorry for these simple questions but I just begun to code iphone app and I really need some help with regards to twitter api .
    please reply , this is really important and I googled for days and nights without an answer I can understand or use.
    thanks in advance.

  • Bizzle

    I’m having the same problem, everything works like a charm in the simulator, but I’m also getting the “Sorry, that page doesn’t exist!” page when running on the iPhone. What exactly was your solution?

  • srny

    Its very nice, But when i tried to run this app it was giving errors. I am using ios3.0, is this app work for ios3.0

  • http://www.lesensor.com Amir

    I’ve spent almost all day with the code but can’t get it to run. Even the webview ain’t appearing after the first steps. The code is getting compiled clean. Initially it’s giving warnings that the class doesn’t implement the delegate method, anyways i do the change and now it ain’t giving any error but nothing is happening. I’ve tried it with your consumer key and consumer secret but later I added my own app’s creds but even then no gain. where am i wrong?? any Help?

  • Kyle

    I also have all of these same errors. They appear as soon as your download the source and compile. A solution to these would be a big help because i think it’s simple, i just can’t figure it out.

  • srny

    When i complie this on ios3.2, ios4.0 it was compling. Thank u

  • srny

    when i include this app on my application it was giving error: libxml/xmlreader.h: No such file or directory and i installed the libxml2.dylib and added the $(SDKROOT)/usr/include/libxml2 line I’m still having 140 errors. Help me out what the problem it may.

  • raj

    Hi, i am getting some problems,
    tweets not posting and not updating. but i see all my tweets.
    i try with u r key/secret its working perfectly why not with my keys.
    i create twitter app with client and i did exactly what u said. i don’t know what is the problem
    please help me i really need this :-(
    Thank you

  • Ajay

    Hi…,

    Thanks for such a great tutorial explaining the use of Twitter API .I works really well for me.Now I am able to integrate this API with my app but still it has some issues with me:

    1) While using
    [_engine getFollowedTimelineSinceID:1 startingAtPage:1 count:100]; it should return 100 records which I am not getting.As although it supports 200 counts.What I am getting is just less than 20 recent twits using this.
    Please suggest me where I am wrong / what should I do to get all the twits from my FollowedTimeLine.Do i need to make any changes ??

    2)when I want to reply somebody,I am using
    [_engine sendUpdate:@"hi" inReplyTo:(unsigned long)[(Tweet*)[appDel.twitAry objectAtIndex:0] TwitID]];
    I tried a lot for converting an string to unsigned long,which results in the truncation of the number or either getting the wrong id.
    So,help me with this issue…how can i pass a string variable by conversion to unsigned long.

    Now I am really got stuck here…..not able to move further in my App. So,please help me asap.

    Thanks in advance!!!!

  • moxide

    How does one need to set up the Twitter app in order for it to work the same way as yours? I made an app and typed in a callback URL and now when use my app id and secret in this project, it redirects me to the callback url and the webview stays on top (showing my callback url page). Using your app id and secret causes the webview to close after successful login. I want mine to do the same, so can you give some info on how to configure the Twitter app?

  • moxide

    How does one need to set up the Twitter app in order for it to work the same way as yours? I made an app and typed in a callback URL and now when use my app id and secret in this project, it redirects me to the callback url and the webview stays on top (showing my callback url page). Using your app id and secret causes the webview to close after successful login. I want mine to do the same, so can you give some info on how to configure the Twitter app (especially what to put and what not in the callback url)?

  • moxide

    Got it. Just don’t provide any callback url :-)

  • Justin

    Hi,

    Thanks for the great tutorial. Is their a way to have the login credentials open when either of the buttons are pressed? Thanks.

  • http://www.cnblogs.com/mainPage wangqiulei

    hi,
    Thanks, I there was a problem,SA_OAuthTwitterEngineDelegate Not called,I did not find the message to print。
    I would like to determine whether the login is successful, if successful, I will create a new view。
    Want you help!!

  • Dong

    I also have the same problem – as your #1 question.
    For me, regardless of what count: I set, I always get 10 tweets only.
    Did you find solution yet?

    Thanks!

  • nanda

    hi i am working on Twitter client- i am following the same tutorial, using MGTwitter and OAuth and i am Authenticating and getting Token, but how to store the Token and send back with user request
    thank you

  • nanda

    hi i am working on Twitter client- i am following the same tutorial, using MGTwitter and OAuth and i am Authenticating and getting Token, but how to store the Token and send back with user request, what to do next
    thank you
    can you help me

  • alpertayfun

    Where is special framework ? How can i include ?

  • http://brainwashinc.wordpress.com/2011/01/10/dealing-with-the-twitter-oauth-apocalypse-icodeblog/ Dealing with the Twitter Oauth-Apocalypse | iCodeBlog « Brainwash Inc. – iPhone/Mobile Development

    [...] via Dealing with the Twitter Oauth-Apocalypse | iCodeBlog. [...]

  • http://qdevarena.blogspot.com Quakeboy

    thank you soo much.. better twitter iphone integration article ever!

  • http://qdevarena.blogspot.com Quakeboy

    I get 140 errors too.. I did add the libxml2.dylib.. still errors persist ?

  • http://qdevarena.blogspot.com Quakeboy

    Tell us how please.

  • http://qdevarena.blogspot.com Quakeboy

    ok.. adding it in project properties instead of target solved..

  • http://qdevarena.blogspot.com Quakeboy

    I solved it too.. posted in below comments about how.. thanks

  • carlos

    Thanks for the wonderful tutorial, and the Xcode project (which compiled perfectly).

    Is there a way to make the project not use a UIWebView, and instead use a standard UIViewController with a couple of UITextFields for the email and password? I’d prefer this for UI consistency within the app.

  • Sky Larking

    How can one add the Twitter username to the tweets listed in the Timeline? The tweet list is very cool and works great, but you cannot tell who the tweets originated from….

  • Nick

    Hi,

    Is it possible to use this code with Application Type set as “Browser” in twitter. I made some changes and was able to make it work fine. But I am trying to find out a way of passing the callbackURL through code rather than hardcoding it on twitter’s settings.

  • umer sufyan

    Hey thanks for the tutorial it is great for iphone but when you upgrade the code to ipad the View is not dismissing by self after authenticating, I mean when you run the same to code for ipad after authentication the View IS not disabling by self this pice of code is not working
    if ([_delegate respondsToSelector: @selector(OAuthTwitterController:authenticatedWithUsername:)]) [_delegate OAuthTwitterController: self authenticatedWithUsername: _engine.username];
    [self performSelector: @selector(dismissModalViewControllerAnimated:) withObject: (id) kCFBooleanTrue afterDelay: 1.0];
    on ipad but great for iphone how will you handle the above code for ipad ??
    Any Idea..?

  • mvaios

    I had the same problem with the tweets count parameter. To solve it just uncomment these lines:
    if (params) {
    fullPath = [self _queryStringWithBase:fullPath parameters:params prefixed:YES];
    }
    in SA_OAuthTweeterEngine.m file.

  • Mike

    I have implemented the code and it works except I am getting a warning. The warning is:
    warning: no ‘-initWithTweetDictionary:’ method found in the iCodeOauthViewController.m How can this be resolved?

    Thank you.

  • Mike

    Hi, I have a tabbar iphone app. The code is covering or hiding my tabbar. How can I fix this? thanks in advance.

  • Aman

    How to logout user once he signed in? Urgent please……

  • Akram Khan

    Great Example…..
    thanks for the tutorial it is great for iphone

  • Akram khan triffort

    :-( it’s woking on my system but not on other sytem

  • http://www.capitolhill.ca Daniel B

    Just a word of thanks for the tutorial. It was very helpful and much appreciated.

  • http://www.capitolhill.ca Daniel B

    I haven’t read all the comments, so I apologize if someone has already mentioned this…

    Again, an excellent tutorial, but I got caught up on one minor issue, which other newbies might also find frustrating. Refer to:


    EDIT: I forgot to include here that you must also include a special XML library for the build to be successful. The Framework is called libxml2.dylib. You can find it at

    /Macintosh HD/Developer/Platforms/iPhoneOS.platform/Developer/SDK/iPhoneOS4.1SDK/usr/lib

    I initially thought that this path was supposed to be added alongside $(SDKROOT)/usr/include/libxml2 in Header Search Paths. It took me a while to figure out that I was simply supposed to add the library in the General tab of Targets->iCodeOAuth->Get Info. Silly, I know, but like I said, I’m new to all this. Also note that the path to the library provided will vary from system to system. For example, I found this library at:

    /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.2.sdk/usr/lib

    on my machine.

    I hope this was helpful.