3

I'm trying to acquire the accessToken value from Twitter for using it in my app (I need to use API v1.1's Authentication Model for GET statuses/user_timeline); I have registered my app on api.twitter.com, imported the AFOAuth1Client classes in the project, and this is the simple code:

- (void)viewDidLoad
{
    self.twitterClient = [[AFOAuth1Client alloc] initWithBaseURL:
                                     [NSURL URLWithString:@"https://api.twitter.com/"] key:@"MYKEY" secret:@"MYSECRETKEY"];
    AFOAuth1Token *accessToken;

    [self.twitterClient acquireOAuthAccessTokenWithPath:@"oauth/request_token" requestToken:accessToken accessMethod:@"GET" success:^(AFOAuth1Token *accessToken) { // I have tried also accessMethod: @"POST"
        NSLog(@"Success: %@", accessToken);
    } failure:^(NSError *error) {
        NSLog(@"Error: %@", error);
    }];
}

Unluckly XCode give me this error:

Error: Error Domain=AFNetworkingErrorDomain Code=-1011 "Expected status code in (200-299), got 401" UserInfo=0x79a14f0 {NSLocalizedRecoverySuggestion=Failed to validate oauth signature and token, AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse: 0x7956390>

What is wrong here? DO i need to REGISTER app on api.twitter.com? Is it the right way, or, what is the simpler way to Get statuses/user_timeline using API v1.1's Twitter Authentication Model in iOS? Thank you!

EDIT: possible waypoint?

1) register a new app on dev.twitter.com

2) in OAuth settings, read Consumer key and Consumer secret

3) set default app access type to read? or read/write? ask for access tokens? use this values in.... ?

SILminore
  • 509
  • 3
  • 10
  • 28

3 Answers3

21

It's been a few days since Twitter added an application only mode. In this mode, you can access specific API endpoints without user's context, ie. your users don't have to authenticate. Only the application does authenticate once in a while to get a "bearer token" which is then sent in every request.

The following code gets a bearer token and then retrieves the public timeline for @barackobama.

STTwitterAPI *twitter = [STTwitterAPI twitterAPIApplicationOnlyWithConsumerKey:@""
                                                                consumerSecret:@""];

[twitter verifyCredentialsWithSuccessBlock:^(NSString *bearerToken) {

    NSLog(@"Access granted with %@", bearerToken);

    [twitter getUserTimelineWithScreenName:@"barackobama" successBlock:^(NSArray *statuses) {
        NSLog(@"-- statuses: %@", statuses);
    } errorBlock:^(NSError *error) {
        NSLog(@"-- error: %@", error);
    }];

} errorBlock:^(NSError *error) {
    NSLog(@"-- error %@", error);
}];

See STTwitter iOS demo project for a working example (use you own consumer key / secret).

nst
  • 3,862
  • 1
  • 31
  • 40
  • Thank you Nicolas @nst, this is perfect! But, what's the point about "bearer token"? There is a RATE LIMITING for this, and I can find the requests alloted for GET statuses/home_timeline with application-only auth are 300 in 15 minutes (not enough!). So, for example, I could have ONLY 300 USERS (or requests) calling `getUserTimelineWithScreenName` from my app in 15 minutes, right? Or, better, how many request of public timeline can do EVERY USER of my app in a certain time? Thank you again! – SILminore Mar 15 '13 at 09:16
  • I cannot answer about Twitter's intents. I can just say that, technically, you can query `application/rate_limit_status` https://dev.twitter.com/docs/api/1.1/get/application/rate_limit_status to know the rate limits. – nst Apr 03 '13 at 15:15
  • @Huxley, have you found any solution regarding rate limiting issue, as i have tested this and yes its allowing only 300 requests in 15 mins so this limit is too less. – prasad Aug 06 '13 at 12:02
  • Looks like the class method has been updated to: + (instancetype) twitterAPIAppOnlyWithConsumerKey:(NSString *)consumerKey consumerSecret:(NSString *)consumerSecret; – Brody Robertson Jan 03 '15 at 00:16
  • nst, I have referred to that demo. How can I save 'access token' and 'access token secret'. Also I do not know how I can check whether they are validated, so user will not have to login every time. – NSPratik May 18 '15 at 06:41
  • Access token storage is out of scope of STTwitter. You can check that tokens are valid with the GET account/verify_credentials endpoint, used by the -[STTwitterAPI getAccountVerifyCredentialsWithSuccessBlock: errorBlock]. – nst May 20 '15 at 13:20
3

If you have your own consumer tokens, you can use the STTwitter library I wrote.

STTwitterAPI *twitter =
  [STTwitterAPI twitterAPIWithOAuthConsumerName:@""
                                    consumerKey:@"your_key"
                                 consumerSecret:@"your_secret"
                                       username:@"username"
                                       password:@"password"];

[twitter verifyCredentialsWithSuccessBlock:^(NSString *username) {

    NSLog(@"Access granted for %@", username);

    [twitter getUserTimelineWithScreenName:@"barackobama"
                              successBlock:^(NSArray *statuses) {
        NSLog(@"-- statuses: %@", statuses);
    } errorBlock:^(NSError *error) {
        NSLog(@"-- error: %@", error);
    }];

} errorBlock:^(NSError *error) {
    NSLog(@"-- error %@", error);
}];

If your tokens are not 'xAuth' enabled, you'll have to use a PIN. STTwitter provides simple asynchronous block-based methods to ask the user. You can also choose to automate the PIN retrieval, see STTwitterDemo -[AppDelegate guessPIN:] for an automated process.

nst
  • 3,862
  • 1
  • 31
  • 40
  • Thank you again, @nst, I had already seen your nice library! The question is simple: I need only to retrieve PUBLIC status/user_timeline from a single twitter account, in JSON format, to parse it and populate a UITableView. What must I do? I have registered my app on dev.twitter.com and now I have only Consumer key and Consumer secret, but now? do we need to ask authorization FOR EACH USER of my app, or there is another way? Please can u write the possible solution point to point? Thanks! – SILminore Feb 19 '13 at 16:32
  • 1
    Twitter API version 1.1 requires every API call to be authenticated https://dev.twitter.com/blog/changes-coming-to-twitter-api so you can either 1) ask the user to login (painful, and not all users have Twitter accounts) 2) embed or download some Twitter account credentials (dangerous) 3) generate your own timeline.json on your server and call it from your application (necessitates to maintain something server side). I probably would personally go for option 3. – nst Feb 19 '13 at 21:27
  • Huh, it so hard!? I suspected it, EACH USER must be authenticated (right, not all have twitter accounts!), but its possible? There isnt other simple way to retrieve a PUBLIC user timelines (ex: RSS, feeds)? I'm thinking about all the apps that now are using UNauthenticated mode (as I can see after march 2013 there will not be unauthenticated api calls), they are really going to panic. Thanks! – SILminore Feb 20 '13 at 09:27
  • "we've decided to discontinue support for XML, Atom, and RSS" https://dev.twitter.com/docs/api/1.1/overview – nst Feb 20 '13 at 09:54
0

STTwitter is simple for use . Also I added example that you can get public twitter timeline

Erhan Demirci
  • 4,173
  • 4
  • 36
  • 44