Post to a Twitter Account from the iPhone

This is the third tip in a series of four that is based on content from the O’Reilly book Head First iPhone Development. This tip is from a code sample in Chapter 3 – Objective-C for the iPhone, and shows how to post to a Twitter account.

Twitter URL Request

The first step is to setup the appropriate URL to post to a twitter account, replace your twitter account and password for the placeholder values.

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:
  [NSURL URLWithString:@"http://TWITTER_ACCOUNT:PASSWORD@twitter.com/statuses/update.xml"] 
  cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0];
Data Related Setup

With the URL ready, we need to setup the HTTP request types as well as the text to twit:

// The text to post
NSString *msg = @"testing";
 
// Set the HTTP request method
[request setHTTPMethod:@"POST"];
 
[request setHTTPBody:[[NSString stringWithFormat:@"status=%@", msg] 
    dataUsingEncoding:NSASCIIStringEncoding]];
 
NSURLResponse *response;
NSError *error;
 
if ([NSURLConnection sendSynchronousRequest:request 
    returningResponse:&response error:&error] != nil)
  NSLog(@"Posted to Twitter successfully.");
else 
  NSLog(@"Error posting to Twitter.");
Asynchronous Requests

Notice in the code above that the URL connection request is sent synchronously, so the UI will block waiting for this to return. One relatively straightforward option is to wrap the above code inside a method, and call that method in a background thread.

For example, in the example below I’ve added the code into a method named postToTwitter, and requested this method to run in a new thread. The example is a little contrived as you wouldn’t hard-code the text to post to Twitter, however, you get the idea.

- (void) postToTwitter
{
  // Since this will be launched in a separate thread, we need
  // an autorelease pool
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 
  NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:
    [NSURL URLWithString:@"http://TWITTER_ACCOUNT:PASSWORD@twitter.com/statuses/update.xml"] 
    cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0];
 
  // The text to post
  NSString *msg = @"testing";
 
  // Set the HTTP request method
  [request setHTTPMethod:@"POST"];
 
  [request setHTTPBody:[[NSString stringWithFormat:@"status=%@", msg] 
    dataUsingEncoding:NSASCIIStringEncoding]];
 
  NSURLResponse *response;
  NSError *error;
 
  if ([NSURLConnection sendSynchronousRequest:request 
      returningResponse:&response error:&error] != nil)
    NSLog(@"Posted to Twitter successfully.");
  else 
    NSLog(@"Error posting to Twitter."); 
 
  // Release pool
  [pool release]; 
}    
 
...
 
[NSThread detachNewThreadSelector:@selector(postToTwitter)
   toTarget:self withObject:nil];
  1. When using +detachNewThreadSelector: you have to set up a NSAutoreleasePool in that method. Otherwise you’ll be leaking memory!

    • Thanks for pointing that out Fabian, I’ve added code inside the method postToTwitter to allocate/free an autorelease pool.

  2. You can also just do an asynchronous http request by replacing your call to sendSynchronousRequest with:

    [NSURLConnection connectionWithRequest: request delegate: some_class]

    Where some_class is an instance of a class that implements delegate functions (e.g. connectionDidFinishLoading:conection, connection:DidReceiveData, etc). Any processing will be done in the current thread, but it likely pales in comparison to the latency of the http request.

  3. Hello John,

    Thanks for the code example. Very useful.
    Can you explain how one can find out if the user provided incorrect credentials? At the moment the code logs “Posted successfully to Twitter” even if the password is incorrect.

    Many thanks,
    Joe

  4. Hi all!

    To find out if users provided incorrect credentials you can do this:

    NSURLResponse* response;
    NSError* error;
    NSData* result = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&response error:&error];

    NSSting *resultString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
    NSLog(@”%@”,resultString);

    [resultString release];

    “resultString” is the response to the request. all you have to do now is to parse it.

Comments are closed.