API requests with TWRequest

Updated on Mon, 2012-06-04 14:19

Overview

TWRequest is a class in the Twitter framework for iOS5 that encapsulates HTTP requests to Twitter’s REST API. The object can also handle authenticating users for the caller.

Recommended Reading

The following articles on Apple's Developer Site will help you as you work with TWRequest:

How do I perform requests with TWRequest?

With TWRequest, you can perform both unauthenticated requests and authenticated requests to the Twitter REST API. The real power lies in the seamless way it handles authenticated requests, but to start, we will demonstrate how you can use it to generate unauthenticated requests to the API.

Unauthenticated Requests

For this example, consider a situation where you would like to retrieve the public timeline for a Twitter user with GET statuses/user_timeline. The one required parameter that we must pass to the endpoint is screen_name, but for illustration purposes, we will also pass other options to the endpoint: count, to limit the returned results, include_entities to see the entities for each object, and include_rts to include the user’s retweets in the responses.

  • screen_name - theSeanCook
  • count - 5
  • include_entities - 1
  • include_rts - 1

The equivalent HTTP request would be of this format:

GET http://api.twitter.com/1/statuses/user_timeline.json?screen_name=theSeanCook&count;=5&include;_entities=1&include;_rts=1

To use TWRequest to make this unauthenticated request, we would do the following:

Source Code Notes:

  • This example utilizes Automatic Reference Counting (ARC).
  • Extraneous line breaks are added for clarity
    1. //  First, we create a dictionary to hold our request parameters
    2. NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
    3. [params setObject:@"theSeanCook" forKey:@"screen_name"];
    4. [params setObject:@"5" forKey:@"count"];
    5. [params setObject:@"1" forKey:@"include_entities"];
    6. [params setObject:@"1" forKey:@"include_rts"];
    7.  
    8. //  Next, we create an URL that points to the target endpoint
    9. NSURL *url = 
    10.   [NSURL URLWithString:@"http://api.twitter.com/1/statuses/user_timeline.json"];
    11.  
    12. //  Now we can create our request.  Note that we are performing a GET request.
    13. TWRequest *request = [[TWRequest alloc] initWithURL:url 
    14.                                          parameters:params 
    15.                                       requestMethod:TWRequestMethodGET];
    16.  
    17. //  Perform our request
    18. [request performRequestWithHandler:
    19.   ^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
    20.  
    21.     if (responseData) {
    22.       //  Use the NSJSONSerialization class to parse the returned JSON
    23.       NSError *jsonError;
    24.       NSArray *timeline = 
    25.         [NSJSONSerialization JSONObjectWithData:responseData 
    26.                                         options:NSJSONReadingMutableLeaves 
    27.                                           error:&jsonError];
    28.  
    29.       if (timeline) {
    30.         // We have an object that we can parse
    31.         NSLog(@"%@", timeline);
    32.       } 
    33.       else { 
    34.         // Inspect the contents of jsonError
    35.         NSLog(@"%@", jsonError);
    36.       }
    37.   }
    38. }];

Authenticated Requests

The real power of TWRequest is its handling of user authentication. In this example, we will first query the accounts that the user has stored on the device, then for the first account returned we retrieve the user's home timeline using GET statuses/home_timeline, which requires authentication. We will once again pass a parameter to the endpoint, include_rts, to illustrate how easy it is to do so with TWRequest.

  • include_rts - 1

The equivalent HTTP request would be an OAuth-signed request of this format:

GET http://api.twitter.com/1/statuses/home_timeline.json?include_rts=1

To use TWRequest to make this authenticated request, we would do the following:

Source Code Notes:

  • This example utilizes Automatic Reference Counting (ARC).
  • Extraneous line breaks are added for clarity
    1. //  First, we need to obtain the account instance for the user's Twitter account
    2. ACAccountStore *store = [[ACAccountStore alloc] init];
    3. ACAccountType *twitterAccountType = 
    4.   [store accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];
    5.  
    6. //  Request permission from the user to access the available Twitter accounts
    7. [store requestAccessToAccountsWithType:twitterAccountType 
    8.                  withCompletionHandler:^(BOOL granted, NSError *error) {
    9.   if (!granted) {
    10.     // The user rejected your request 
    11.     NSLog(@"User rejected access to the account.");
    12.   } 
    13.   else {
    14.     // Grab the available accounts
    15.     NSArray *twitterAccounts = 
    16.       [store accountsWithAccountType:twitterAccountType];
    17.  
    18.     if ([twitterAccounts count] > 0) {
    19.       // Use the first account for simplicity 
    20.       ACAccount *account = [twitterAccounts objectAtIndex:0];
    21.  
    22.       // Now make an authenticated request to our endpoint
    23.       NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
    24.       [params setObject:@"1" forKey:@"include_entities"];
    25.  
    26.       //  The endpoint that we wish to call
    27.       NSURL *url = 
    28.         [NSURL 
    29.         URLWithString:@"http://api.twitter.com/1/statuses/home_timeline.json"];
    30.  
    31.       //  Build the request with our parameter 
    32.       TWRequest *request = 
    33.         [[TWRequest alloc] initWithURL:url 
    34.                             parameters:params 
    35.                          requestMethod:TWRequestMethodGET];
    36.  
    37.       // Attach the account object to this request
    38.       [request setAccount:account];
    39.  
    40.       [request performRequestWithHandler:
    41.         ^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
    42.         if (!responseData) {
    43.           // inspect the contents of error 
    44.           NSLog(@"%@", error);
    45.         } 
    46.         else {
    47.           NSError *jsonError;
    48.           NSArray *timeline = 
    49.             [NSJSONSerialization 
    50.               JSONObjectWithData:responseData 
    51.                          options:NSJSONReadingMutableLeaves 
    52.                            error:&jsonError];            
    53.           if (timeline) {                          
    54.             // at this point, we have an object that we can parse
    55.             NSLog(@"%@", timeline);
    56.           } 
    57.           else { 
    58.             // inspect the contents of jsonError
    59.             NSLog(@"%@", jsonError);
    60.           }
    61.         }
    62.       }];
    63.  
    64.     } // if ([twitterAccounts count] > 0)
    65.   } // if (granted) 
    66. }];