ios twitter framework

24
iOS Twitter framework iOS Twitter framework Updated on Fri, 2012-04-13 08:19 1. Overview 2. Go to the source 3. What can I do with the framework? 4. Single Sign-On 5. Distribution 6. Instant Personalization 7. Accessing the Twitter API 8. Have questions?

Upload: nickyu

Post on 25-Jul-2015

710 views

Category:

Documents


1 download

TRANSCRIPT

iOS Twitter framework

iOS Twitter framework

Updated on Fri, 2012-04-13 08:19

1. Overview2. Go to the source3. What can I do with the framework?4. Single Sign-On5. Distribution6. Instant Personalization7. Accessing the Twitter API8. Have questions?

OverviewWith iOS5, Apple has introduced a new framework that enables your iOS applications to leverage the power of Twitter. The framework removes many of the common obstacles encountered when accessing Twitter’s API, including authentication and Tweet composition, and allows developers to focus on more meaningful levels of integration that enrich their application experiences.

Go to the sourceWith the Twitter framework, as with any iOS-related topic, the Apple Developer Site should be considered the ultimate source of development references, guides and code for developers. It is also where you should start if you encounter generic iOS issues that you cannot resolve on your own.

WWDC informationThe Twitter integration was announced at the 2011 WWDC Keynote (announcement is at 49:03). Additionally, Developer Session 124, “Twitter Integration,” was held to introduce to framework to developers. You should at least review the WWDC Session 124 video before proceeding with your integration.

Documentation, example and forumsApple’s Developer Library includes many guides and references that can assist you if you need help. Before attempting to build an iOS5 Twitter integration, it is highly recommended that you review the following:

• The Twitter Framework Reference documents the classes in the framework.• The Account Framework Reference documents the Account framework, which is used in

conjunction with Twitter.framework.• The official Twitter framework example from Apple is available for download.

Finally, the Apple Developer Forums are a great place to have your questions answered by Apple employees and developers in the iOS ecosystem.

What can I do with the framework?As a mobile application developer, there are 3 key facets of the Twitter framework that you can leverage in your applications:

1. Single Sign-On2. Distribution3. Instant Personalization

In addition to these main integration points, the framework also makes it incredibly easy to integrate your application with any of Twitter's APIs by handling common obstacles, such as authentication, for you so you can focus on building an amazing experience for your users. To help developers understand the integration potential for their own products, we have highlighted 10 showcase applications that leverage the framework at http://ios.twitter.com.

As always, be aware that if your application accesses Twitter, it is bound to the Twitter Terms of Service.

iOS Twitter framework

Single Sign-OnWith iOS5, a user’s Twitter credentials are stored in a central account store, ACAccountStore, that is accessible from applications on the device. The first time that an application attempts to access a user's Twitter account, a user is presented a dialog requesting access to his or her Twitter account:

Figure 1: The Account Access Prompt

Once a user has granted permission to an application, the user is not prompted again. The experience is very similar to that of an application that leverages Location Services in that once a user has either granted or rejected access for the application, the prompt is not shown again.

A user may manually add his credentials, or an application can provide pre-verified OAuth tokens and secrets to add the user’s Twitter account to the device. The latter scenario is useful for applications that have already authenticated users, either on the device or on a server-side integration. The process for migrating existing tokens to core accounts is explained at Migrating tokens to system accounts.

Reverse AuthenticationIf your application requires signed authentication tokens from the device for a server-side integration, you can do so with a special process called “Reverse Auth”. More information about Reverse Auth is described at Using Reverse Auth.

Once a user’s Twitter account has been stored on the device, any application on the device can request access from the user to make authenticated requests on his or her behalf.

DistributionThe Twitter framework contains a standard, easy-to-invoke dialog for composing Tweets, TWTweetComposeViewController, that is also commonly referred to as the “Tweet Sheet.” With this dialog, you can set initial text, images, and links and present the composition to the user in a modal window. The user has the ability to edit the content of the Tweet before sending, including content that you set before presenting the view.

The Tweet Sheet contains built-in functionality that enriches the user’s experience: The user can add his location and select from multiple accounts, and the Tweet Sheet will also auto-complete user names for the user while they are typing free-form text.

iOS Twitter framework

Figure 2: The Tweet Sheet

iOS Twitter framework

Instant PersonalizationMobile devices provide valuable signals that can be used to personalize and enrich a user’s experience; for example, a device's GPS, if available programmatically, provides details on where a user is geographically that the developer can use to display localized information. Now with the Twitter framework, you can personalize your application’s experience for a user based on the user’s interest graph in addition to these other signals to create unique, targeted mobile apps.

Consider the scenario where a new user downloads and opens your application for the first time. At this point, you know very little about the user, but if the user has a Twitter account configured on the device, you can quickly--and easily--surface relevant content to the user based on his Twitter timeline. This instant personalization is key to building a relationship with your user, and will increase the likelihood that the user returns to your application.

Accessing the Twitter APIThe Twitter framework provides TWRequest which encapsulates requests to Twitter’s REST API and handles user authentication seamlessly. With TWRequest, you can cleanly separate your requests to Twitter and process the results using block-based handlers. When you need to make authenticated calls on a user's behalf, you do so by attaching a local Twitter account instance, instead of manually performing an OAuth signing operation. For more information, TWRequest is documented with examples at API requests with TWRequest.

What about Direct Messages?The Twitter framework cannot read or delete Direct Messages but it can send them. If your application requires the ability to read or delete Direct Messages, you must follow the traditional OAuth web flow to obtain the user’s permission. You should then use the returned access token and secret for future calls that require DM read permission.

Have questions?If you have questions that you would like to ask the developer community, as well as Twitter's developer advocates, please post them in the Mobile Development Discussion Forum.

iOS Twitter framework

Adding the Twitter FrameworkUpdated on Mon, 2011-10-31 13:11

OverviewStarting with iOS5, Apple has added a Twitter Framework to iOS. With this Framework, you can easily leverage the power of Twitter for single sign-on, content personalization and content sharing. This document walks you through the simple process of adding Twitter to a new or existing project.

Apple's DocumentationFor general iOS and XCode documentation, please refer to Apple's Developer Site. Apple's Developer Library contains, among many other outstanding articles, the following relevant topics:

• XCode 4 User Guide• Adding an Existing Framework to a Project• Twitter Framework Reference

Adding the Framework to your Application

To begin, open your application in XCode.

iOS Twitter framework

In the project explorer, select the target that you would like to link against Twitter.framework. In this example, the target name is TwitterExample.

Next, find the "Linked Frameworks and Libraries" module. You may have to expand the entry. Click the "+" sign to add a new Framework.

iOS Twitter framework

In the search field, enter "Twitter" and select the Twitter.Framework entry and click the "Add" button. Note that you may have to expand the "iOS 5.0" entry to see the framework.

You have now successfully added the framework to your project. If you encounter any problems, please raise a question in the Twitter API Discussion Forums.

iOS Twitter framework

API requests with TWRequestUpdated on Mon, 2012-06-04 14:19

OverviewTWRequest 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 ReadingThe following articles on Apple's Developer Site will help you as you work with TWRequest:

• TWRequest Class Reference• ACAccount Class Reference• NSJSONSerialization Class Reference• A Short Practical Guide to Blocks

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:

iOS Twitter framework

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 parameters2. 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 endpoint9. 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 request18. [request performRequestWithHandler:19. ^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {20.  21. if (responseData) {22. // Use the NSJSONSerialization class to parse the returned JSON23. 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 parse31. NSLog(@"%@", timeline);32. } 33. else { 34. // Inspect the contents of jsonError35. NSLog(@"%@", jsonError);36. }37. }38. }];

Authenticated RequestsThe 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:

iOS Twitter framework

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 account2. ACAccountStore *store = [[ACAccountStore alloc] init];3. ACAccountType *twitterAccountType = 4. [store accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];5.  6. // Request permission from the user to access the available Twitter accounts7. [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 accounts15. 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 endpoint23. NSMutableDictionary *params = [[NSMutableDictionary alloc] init];24. [params setObject:@"1" forKey:@"include_entities"];25.  26. // The endpoint that we wish to call27. 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 request38. [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 parse55. NSLog(@"%@", timeline);

iOS Twitter framework

56. } 57. else { 58. // inspect the contents of jsonError59. NSLog(@"%@", jsonError);60. }61. }62. }];63.  64. } // if ([twitterAccounts count] > 0)65. } // if (granted) 66. }];

iOS Twitter framework

Posting images using TWRequestUpdated on Wed, 2012-02-01 17:53

OverviewThe Twitter framework's TWRequest encapsulates calls to the Twitter API, including signing the request on behalf of the user. With Twitter's photo hosting service, and its API endpoint POST statuses/update_with_media, it is possible to post a Tweet and a status simultaneously via a TWRequest.

Code ExampleBefore posting a Tweet with an attached image, you should check GET help/configuration to check the characters_reserved_per_media and max_media_per_upload values. The former tells you how many characters out of 140 you should reserve for the URL of the posted image, while the latter tells you the number of images that you can attach to the Tweet.

Once you know the current Twitter configuration, you can post the Tweet. You use the TWRequest just as you would for any Twitter API call, but make sure that both the data and the status' text as "multipart/form-data."

Notes:

• This example utilizes Automatic Reference Counting (ARC).• Extraneous line breaks are added for clarity

4. - (void)performTWRequestUpload5. {6. NSURL *url = 7. [NSURL URLWithString:8. @"https://upload.twitter.com/1/statuses/update_with_media.json"];9.  10. // Create a POST request for the target endpoint11. TWRequest *request = 12. [[TWRequest alloc] initWithURL:url 13. parameters:nil 14. requestMethod:TWRequestMethodPOST];15.  16. // self.accounts is an array of all available accounts; 17. // we use the first one for simplicity18. [request setAccount:[self.accounts objectAtIndex:0]];19.  20. // The "larry.png" is an image that we have locally21. UIImage *image = [UIImage imageNamed:@"larry.png"];22.  23. // Obtain NSData from the UIImage 24. NSData *imageData = UIImagePNGRepresentation(image);25.  26. // Add the data of the image with the 27. // correct parameter name, "media[]"28. [request addMultiPartData:imageData

iOS Twitter framework

29. withName:@"media[]" 30. type:@"multipart/form-data"];31.  32. // NB: Our status must be passed as part of the multipart form data33. NSString *status = @"just setting up my twttr #iOS5";34.  35. // Add the data of the status as parameter "status"36. [request addMultiPartData:[status dataUsingEncoding:NSUTF8StringEncoding] 37. withName:@"status" 38. type:@"multipart/form-data"];39.  40. // Perform the request. 41. // Note that -[performRequestWithHandler] may be called on any thread,42. // so you should explicitly dispatch any UI operations to the main thread 43. [request performRequestWithHandler:44. ^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {45. NSDictionary *dict = 46. (NSDictionary *)[NSJSONSerialization 47. JSONObjectWithData:responseData options:0 error:nil];48.  49. // Log the result50. NSLog(@"%@", dict);51.  52. dispatch_async(dispatch_get_main_queue(), ^{53. // perform an action that updates the UI...54. });55. }];56. }

iOS Twitter framework

Using the Tweet SheetUpdated on Mon, 2011-11-07 11:12

OverviewThe Twitter framework includes a powerful all-in-one class for composing Tweets called TWTweetComposeViewController, also known as the "Tweet Sheet". The Tweet Sheet provides multiple mechanisms that enhance the user experience that have previously required developer support to implement:

• The UI of the sheet is handled for you• You can set the initial text of the Tweet, attach images, and attach URLs• The Tweet Sheet handles multiple accounts seamlessly• The controller autocompletes usernames as the user composes the Tweet• It handles counting characters to ensure the 140 character limit

Recommended ReadingThe following items are provided by Apple, and should be consulted first if you have any questions about using TWTweetComposeViewController. As always, you should consider the Apple documentation the definitive source of information for iOS.

• TWTweetComposeViewController reference• The official sample application• WWDC 2011 Session 124, "Twitter Integration"

How do I use the Tweet Sheet in my application?Invoking the Tweet Sheet in your application is quite simple. First, you should ensure that you have added the Twitter.framework to your project as described in Adding the Twitter Framework . Once you have added the framework to your project, using the Tweet Sheet is as simple as:

1. Initialize a Tweet Sheet2. Configure the initial text, images, and URLs that you would like to set (if any)3. Configure the result handler4. Display the Tweet Sheet using -[presentViewController:animated:completion:]

(Note: as of iOS5, this is the preferred method instead of -[presentModalViewController:animated])

Code ExampleBelow is an example of the above steps. Note that the methods for setting initial content respond with Boolean values; this allows you, the developer, to not have to worry about the current count of characters in the body of the Tweet that you are initializing. If the method returns YES, there was enough room to add the content. If the method returns NO, the content you attempted to add would

iOS Twitter framework

result in a Tweet longer than 140 characters. The logic for character counting also takes into effect the current number of characters required for t.co URL wrapping.

Source Code Notes:• This example utilizes Automatic Reference Counting (ARC).• Extraneous line breaks are added for clarity

1. - (void)showTweetSheet2. {3. // Create an instance of the Tweet Sheet4. TWTweetComposeViewController *tweetSheet = 5. [[TWTweetComposeViewController alloc] init];6.  7. // Sets the completion handler. Note that we don't know which thread the8. // block will be called on, so we need to ensure that any UI updates occur9. // on the main queue10. tweetSheet.completionHandler = ^(TWTweetComposeViewControllerResult result) {11. switch(result) {12. case TWTweetComposeViewControllerResultCancelled:13. // This means the user cancelled without sending the Tweet14. break;15. case TWTweetComposeViewControllerResultDone:16. // This means the user hit 'Send'17. break;18. }19.  20.  21. // dismiss the Tweet Sheet 22. dispatch_async(dispatch_get_main_queue(), ^{ 23. [self dismissViewControllerAnimated:NO completion:^{24. NSLog(@"Tweet Sheet has been dismissed."); 25. }];26. });27. };28.  29. // Set the initial body of the Tweet30. [tweetSheet setInitialText:@"just setting up my twttr #iOS5"]; 31.  32. // Adds an image to the Tweet33. // For demo purposes, assume we have an image named 'larry.png'34. // that we wish to attach35. if (![tweetSheet addImage:[UIImage imageNamed:@"larry.png"]]) {36. NSLog(@"Unable to add the image!");37. }38.  39. // Add an URL to the Tweet. You can add multiple URLs.40. if (![tweetSheet addURL:[NSURL URLWithString:@"http://twitter.com/"]]){41. NSLog(@"Unable to add the URL!");42. }43.  44. // Presents the Tweet Sheet to the user45. [self presentViewController:tweetSheet animated:NO completion:^{46. NSLog(@"Tweet sheet has been presented.");47. }];48. }

iOS Twitter framework

Migrating tokens to system accountsUpdated on Mon, 2011-11-07 11:13

OverviewIt is very common for applications to have previously verified and stored a user’s access tokens, either through an existing iOS application or via a server-side integration. To leverage the power of the Twitter framework in iOS5, it is easy to migrate the user's access tokens to the device. This document details that process.

RequirementsThis process requires an application running on iOS5, as well as verified access tokens and secrets for a Twitter user. The iOS target must also link against the Twitter framework and the Accounts framework.

Code ExampleFor this example, consider the scenario where you have already verified and securely stored your user’s access token and secret in an iOS application using xAuth, and would now like to migrate these tokens to the central account store.

Step 1: Add Twitter.framework and Accounts.framework to your projectThe process for adding the Twitter framework is detailed in Adding the Twitter Framework . Follow the same instructions for adding the Accounts framework to your project’s target.

To verify that this step has been completed succesfully, add the following two import statements to an header file in the target project and then verify that things build successfully:

1. #import <Twitter/Twitter.h>2. #import <Accounts/Accounts.h>

Obviously, these two statements should be included in header or implementation files where classes from the two frameworks are utilized.

Step 2: Add the migration codeThe code that transitions tokens to the account store is quite simple, but you should should check for and gracefully handle any error conditions that may arise.

Note: For testing purposes, you can obtain verified tokens to use to validate this process by visiting http://dev.twitter.com/apps, and by viewing the bottom of an application page under the section entitled “Your Access Token”.

Source Code Notes:• This example utilizes Automatic Reference Counting (ARC).• Extraneous line breaks are added for clarity

iOS Twitter framework

1. // A previously-verified OAuth access token and secret for your user2. NSString *token = @"a-verified-access-token-for-your-user";3. NSString *secret = @"a-verified-secret-for-your-user";4.  5. // Next, create an instance of the account store 6. ACAccountStore *store = [[ACAccountStore alloc] init];7.  8. // Each account has a credential, which is comprised of a verified token and

secret9. ACAccountCredential *credential = 10. [[ACAccountCredential alloc] initWithOAuthToken:token tokenSecret:secret];11.  12. // Obtain the Twitter account type from the store13. ACAccountType *twitterAcctType = 14. [store accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];15.  16. // Create a new account of the intended type17. ACAccount *newAccount = [[ACAccount alloc] initWithAccountType:twitterAcctType];18.  19. // Attach the credential for this user20. newAccount.credential = credential;21.  22. // Finally, ask the account store instance to save the account23. // Note: that the completion handler is not guaranteed to be executed24. // on any thread, so care should be taken if you wish to update the UI, etc.25. [store saveAccount:newAccount withCompletionHandler:^(BOOL success, NSError

*error) {26. if (success) {27. // we've stored the account!28. NSLog(@"the account was saved!");29. } else {30. //something went wrong, check value of error31. NSLog(@"the account was NOT saved");32.  33. // see the note below regarding errors... 34. // this is only for demonstration purposes35. if ([[error domain] isEqualToString:ACErrorDomain]) {36.  37. // The following error codes and descriptions are found in ACError.h38. switch ([error code]) { 39. case ACErrorAccountMissingRequiredProperty: 40. NSLog(@"Account wasn't saved because "41. "it is missing a required property.");42. break;43. case ACErrorAccountAuthenticationFailed: 44. NSLog(@"Account wasn't saved because "45. "authentication of the supplied "46. "credential failed.");47. break;48. case ACErrorAccountTypeInvalid: 49. NSLog(@"Account wasn't saved because "50. "the account type is invalid.");51. break;52. case ACErrorAccountAlreadyExists: 53. NSLog(@"Account wasn't added because "54. "it already exists.");55. break;56. case ACErrorAccountNotFound: 57. NSLog(@"Account wasn't deleted because"58. "it could not be found.");59. break;60. case ACErrorPermissionDenied: 61. NSLog(@"Permission Denied");62. break; 63. case ACErrorUnknown: 64. default: // fall through for any unknown errors...65. NSLog(@"An unknown error occurred.");

iOS Twitter framework

66. break;67. }68. } else {69. // handle other error domains and their associated response codes...70. }71. }72. }];

Error conditionsFor the official iOS overview that describes how to handle error conditions, please review the Error Handling Programming Guide in the Apple Developer Library.

If the token migration process is unsuccessful, there are two common error domains that may be returned: ACErrorDomain and NSURLErrorDomain. As demonstrated above, a simple switch statement can help explain any errors related to the storage of accounts, such as ACErrorAccountAlreadyExists, which indicates that you are attempting to store an account that has already been stored.

The Account Store must verify the credentials it is provided by communicating with Twitter, so it is possible that the error returned is in the NSURLErrorDomain. Like all network connectivity errors, these conditions should be gracefully handled in your application. For more information on the various error codes returned in the NSURLErrorDomain, please review the contents of NSURLError.h.

Next StepsOnce you have migrated your user's tokens to core account instances, you should review API requests with TWRequest.

iOS Twitter framework

Using Reverse AuthUpdated on Thu, 2012-04-12 09:48

While the Twitter framework for iOS provides an incredibly easy way to make authenticated calls on behalf of a user to the Twitter API, you may find the need to process a user’s Twitter data on your server. To faciliate this, Twitter provides an endpoint that allows you to obtain the user's OAuth tokens for your own application. The process is called Reverse Auth.

Before We StartReverse Auth is still OAuth.The reverse auth flow is not a complicated process, but it does require the ability to make a signed request. As such, you should be familiar with the request signing process before attempting to use the endpoint. No, seriously. Go read that document. We'll wait.

Your application requires special permissions to use this endpoint.To use Reverse Auth, send a request to [email protected] with plenty of details about your application and why Reverse Auth is the best choice for it.

The Twitter framework is required. Before we begin, you should add the Twitter framework to your project if you have not already. And of course you should ensure that the user has an account saved on the device (otherwise, this exercise will be fruitless). To do this, you can call:

+[TWTweetComposeViewController canSendTweet]

This will return a Boolean that indicates whether or not the user can tweet, and thus whether or not they have an account stored locally. At this point, you now have all that you need to make request an OAuth request token.

Step 1: Obtain a Special Request TokenFirst, you make an HTTPS request to the Twitter Request Token URL https://api.twitter.com/oauth/request_token with your application's consumer key. In addition to the conventional oauth_* signing parameters, you must also include x_auth_mode set to the value reverse_auth.

As an example, consider a request with the following values signed with the token secret ydC2yUbFaScbSlykO0PmrMjXFeLraSi3Q2HfTOlGxQM:

The tokens used here are for demonstration purposes only, and will not work for you.

• oauth_consumer_key JP3PyvG67rXRsnayOJOcQ• oauth_nonce 1B7D865D-9E15-4ADD-8165-EF90D7A7D3D2• oauth_signature_method HMAC-SHA1• oauth_timestamp 1322697052• oauth_version 1.0• x_auth_mode reverse_auth

iOS Twitter framework

These parameters should result in a signature base string that looks like this:

1. POST&https%3A%2F%2Fapi.twitter.com%2Foauth%2Frequest_token&oauth_consumer_key%3DJP3PyvG67rXRsnayOJOcQ%26oauth_nonce%3D1B7D865D-9E15-4ADD-8165-EF90D7A7D3D2%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1322697052%26oauth_version%3D1.0%26x_auth_mode%3Dreverse_auth

This call should result in a response that looks like this. Notice that this response actually looks like an OAuth header.

(line wrapping added for clarity):

1. OAuth oauth_nonce="xq2maKtilFhVTC1MSxVC4cQIJLd53O6w97YmrdOGSk8", 2. oauth_signature_method="HMAC-SHA1", 3. oauth_timestamp="1322697052", 4. oauth_consumer_key="JP3PyvG67rXRsnayOJOcQ", 5. oauth_token="5mgkU82W0PTA0DLgSIA5vFK6c08i8dXzrbLnX06vl38", 6. oauth_signature="aOM%2FwW2kAowAeHBRvw7faH245p0%3D", 7. oauth_version="1.0"

If you receive a response that looks like this:

1. <?xml version="1.0" encoding="UTF-8"?>2. <errors>3. <error code="87">Client is not permitted to perform this action</

error>4. </errors>

Your application's keys have not been enabled for reverse auth privileges. Please see the note above regarding requesting access to the endpoint.

Step 2: Obtain the Access TokenWe are now going to make a request to the OAuth Access Token endpoint, https://api.twitter.com/oauth/access_token, using the TWRequest provided by the Twitter framework. If you are not familiar with TWRequest, review API requests with TWRequest.

You will need to POST to the endpoint and you must include two parameters:

• x_reverse_auth_target Your app's consumer key (e.g. "JP3PyvG67rXRsnayOJOcQ")• x_reverse_auth_parameters The string value returned in Step #1

This code sample includes extraneous line breaks for readability, and uses Automatic Reference Counting (ARC).

1. // Assume that we stored the result of Step 1 into a var 'resultOfStep1'2. NSString *S = resultOfStep1;3. NSDictionary *step2Params = [[NSMutableDictionary alloc] init];4. [step2Params setValue:@"JP3PyvG67rXRsnayOJOcQ" forKey:@"x_reverse_auth_target"];5. [step2Params setValue:S forKey:@"x_reverse_auth_parameters"]; 6.  

iOS Twitter framework

7. NSURL *url2 = [NSURL URLWithString:@"https://api.twitter.com/oauth/access_token"];8. TWRequest *stepTwoRequest = 9. [[TWRequest alloc] initWithURL:url2 parameters:step2Params

requestMethod:TWRequestMethodPOST];10.  11. // You *MUST* keep the ACAccountStore alive for as long as you need an ACAccount instance12. // See WWDC 2011 Session 124 for more info.13. self.accountStore = [[ACAccountStore alloc] init];14.  15. // We only want to receive Twitter accounts16. ACAccountType *twitterType = 17. [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];18.  19. // Obtain the user's permission to access the store20. [self.accountStore requestAccessToAccountsWithType:twitterType 21. withCompletionHandler:^(BOOL granted, NSError *error) {22. " if (!granted) {23. " " // handle this scenario gracefully24. " } else {25. " " // obtain all the local account instances26. " " NSArray *accounts = 27. " " [self.accountStore accountsWithAccountType:twitterType];28.  29. " " // for simplicity, we will choose the first account returned - in your app,30. " " // you should ensure that the user chooses the correct Twitter account31. " " // to use with your application. DO NOT FORGET THIS STEP.32. " " [stepTwoRequest setAccount:[accounts objectAtIndex:0]];33.  34. " " // execute the request35. " " [stepTwoRequest performRequestWithHandler:36. ^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {37. " " " NSString *responseStr = 38. " " " [[NSString alloc] initWithData:responseData 39. encoding:NSUTF8StringEncoding];40.  41. // see below for an example response42. NSLog(@"The user's info for your server:\n%@", responseStr);43. " " }];44. " } 45. }];

If things worked properly, you should receive a response that looks like this.

1. oauth_token=2311112785-EXKeLV5ezo3HHIaIf1T3ffeww0mR5dfYXKZjjRy0&oauth_token_secret=KYxxxxx3U4Fxrxva3BGD92--12ehEzFwQ&user_id=38895958&screen_name=theseancook

iOS Twitter framework

Frequently Asked QuestionsUpdated on Mon, 2012-02-27 18:58

1. Frequent Asked Questions2. I'm receiving authentication errors when using TWRequest. What's going on?3. Do TWRequest and TWTweetComposeViewController calls automatically wrap urls in

statuses updates?4. Why is my application attributed as "from iOS" instead of "from <my application>" on

twitter.com?5. I'm seeing strange crashes when using ACAccounts with TWRequest. What is going on?

Frequent Asked QuestionsThe following is a collection of "gotchas" that have commonly affected developers using the Twitter.framework. If you do not see an answer to your question here, please head to the Mobile Development Discussion Forums and post your question there.

I'm receiving authentication errors when using TWRequest. What's going on?Are you certain that there are accounts stored on the device in Settings.app? No, seriously: are you sure that there are accounts stored on the device? One of the most common errors that developers experience is that they are not checking for the existence of at least one account before calling -[TWRequest setAccount:], and thus the request is sent unauthenticated.

We recommend checking +[TWTweetComposeViewController canSendTweet:] before you perform any actions that may require authentication. Additionally, you can also check the size of the array returned via -[ACAccountStore accountsWithAccountType:].

Do TWRequest and TWTweetComposeViewController calls automatically wrap urls in statuses updates?

Yes. Please review the documentation at t.co Link Wrapper FAQ and POST statuses/update for more information.

Want to see this for yourself? You can verify this behavior on your own with the following code snippet:

1. ACAccountStore *store = [[ACAccountStore alloc] init];2. ACAccountType *twitterType = 3. [store accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];4.  5. [store requestAccessToAccountsWithType:twitterType 6. withCompletionHandler:^(BOOL granted, NSError *error) {7.  8. NSArray *accounts = [store accountsWithAccountType:twitterType];9. NSURL *url = [NSURL URLWithString:@"http://api.twitter.com/1/statuses/update.json"];10. NSDictionary *dict = 11. [NSDictionary dictionaryWithObjectsAndKeys:12. @"This is a test https://dev.twitter.com/discussions/4682", @"status", nil];13.  

iOS Twitter framework

14. TWRequest *request = [[TWRequest alloc] initWithURL:url 15. parameters:dict 16. requestMethod:TWRequestMethodPOST];17.  18. // Use the first account for simplicity19. [request setAccount:[accounts objectAtIndex:0]];20.  21. [request performRequestWithHandler:22. ^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {23. if (responseData) {24. id data = [NSJSONSerialization JSONObjectWithData:responseData 25. options:NSJSONReadingMutableLeaves 26. error:nil];27. // Print out the response. 28. // You can verify that the "text" of the status is now t.co'd.29. NSLog(@"%@", data);30. }31. }]; 32. }];

Why is my application attributed as "from iOS" instead of "from <my application>" on twitter.com?

If your application is not yet live in the App Store:

The application making the requests must be launched in Apple's App Store in order for the attribution to display on twitter.com. Note that the iOS5 version of the application must be live, not just a previous version.

If your application is live in the App Store:

In the majority of cases, your app will automatically be attributed on twitter.com. Please verify these steps if you do not see attribution:

1. Ensure that all the fields on your iOS App Store application record are filled out and valid (e.g. valid URLs in URL fields and so on).

2. Application names on Twitter are shorter than iOS application names. Some long iOS app names will cause attribution not to show.

3. Don't attach "on iOS" "on iPhone" or "on iPad" to your app name4. Don't conflict with an app name already existing and registered on dev.twitter.com.

If you have verified each of these points and you still don't have attribution, please post in the discussion forums for further support.

I'm seeing strange crashes when using ACAccounts with TWRequest. What is going on?

This is a common problem for developers who are not utilizing Automatic Reference Counting (ARC). The solution is to either use ARC in your code, or ensure that you hold onto the ACAccountStore that "owns" the ACAccount that you are using for as long as need the ACAccount. This is the same pattern that holds for such classes as ALAssetsLibrary. To quote the documentation, "The lifetimes of objects you get back from a library instance are tied to the lifetime of the library instance."

iOS Twitter framework