Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS Twitter Reverse OAuth

I have been pouring over the internet for days now trying to figure out how to implement this.

I need to request the access token and secret from twitter in order to pass this to a server that will process the users tweets for my application.

I have been following this link https://dev.twitter.com/docs/ios/using-reverse-auth

The problem is step 1. They dont give you an example of step 1.

Here is my code:

NSURL *url = [NSURL URLWithString:TW_OAUTH_URL_REQUEST_TOKEN];
NSDictionary *parameters = @{TW_X_AUTH_MODE_KEY:TW_X_AUTH_MODE_REVERSE_AUTH};

SLRequest *getTwitterAuth = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodGET URL:url parameters:parameters];


//  Assume that we stored the result of Step 1 into a var 'resultOfStep1'

NSString *S = resultOfStep1;
NSDictionary *step2Params = [[NSMutableDictionary alloc] init];
[step2Params setValue:@"kfLxMJsk7fqIuy8URhleFg" forKey:@"x_reverse_auth_target"];
[step2Params setValue:S forKey:@"x_reverse_auth_parameters"];

NSURL *url2 = [NSURL URLWithString:@"https://api.twitter.com/oauth/access_token"];
SLRequest *stepTwoRequest =
[SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:url2 parameters:step2Params];

//  You *MUST* keep the ACAccountStore alive for as long as you need an ACAccount instance
//  See WWDC 2011 Session 124 for more info.
self.accountStore = [[ACAccountStore alloc] init];

//  We only want to receive Twitter accounts
ACAccountType *twitterType =
[self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];

//  Obtain the user's permission to access the store
[self.accountStore requestAccessToAccountsWithType:twitterType
                             withCompletionHandler:^(BOOL granted, NSError *error) {
     if (!granted) {
         // handle this scenario gracefully
     } else {
         // obtain all the local account instances
         NSArray *accounts =
         [self.accountStore accountsWithAccountType:twitterType];

         // for simplicity, we will choose the first account returned - in your app,
         // you should ensure that the user chooses the correct Twitter account
         // to use with your application.  DO NOT FORGET THIS STEP.
         [stepTwoRequest setAccount:[accounts objectAtIndex:0]];

         // execute the request
         [stepTwoRequest performRequestWithHandler:
          ^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
              NSString *responseStr = 
              [[NSString alloc] initWithData:responseData 
                                    encoding:NSUTF8StringEncoding];

              // see below for an example response
              NSLog(@"The user's info for your server:\n%@", responseStr);
          }];
     } 
 }];

I have been trying to figure out how I process the SLRequest in oder to pass it to step 2 from the twitter docs.

I have also used this here: https://github.com/seancook/TWReverseAuthExample

This code is great but very complex. Any help would be greatly appreciated! Thanks!

like image 277
Kyle Begeman Avatar asked May 31 '13 16:05

Kyle Begeman


3 Answers

The reason step one doesn't have any code is that they assume you will do this on your server or before hand or something like that. Basically you need to generate a key that your app will use to convert iOS tokens to normal tokens.

There is a script that will make the request for you here: http://www.ananseproductions.com/twitter-reverse-auth-headaches/ Its written in ruby so you could use something similar if you have a ruby server.

Personally I would have my app request this token from my server, then make the request to twitter, then post the new token back to my server.

like image 198
Patrick Tescher Avatar answered Nov 13 '22 12:11

Patrick Tescher


Here is a class to help accomplish just this with a single method call that returns a dictionary with the token and token secret.

https://github.com/kbegeman/Twitter-Reverse-Auth

Hope this helps others out!

like image 31
Kyle Begeman Avatar answered Nov 13 '22 12:11

Kyle Begeman


As of this code https://github.com/seancook/TWReverseAuthExample , it's fairly simple to implement in your own application. I prefer to create reusable classes, so I don't have to implement the same code multiple times. Normally you would create some singleton and work with it on the following tutorial. However the point of this instruction is not to teach you how to create singletons, so for the simplicity sake, we will use AppDelegate.h/m which is easily accessible from all over the application.

All you have to do is the following:

  1. Open yours and Sean Cook's project (the one which URL is above)

  2. Drag and copy Source->Vendor->ABOauthCore group into your project

  3. Select TWAPIManager.h/m, TWSignedRequest.h/m and copy them into your project

  4. Add the below code into your AppDelegate.h file

    @property (nonatomic, strong) ACAccountStore* store;

    @property (nonatomic, strong) TWAPIManager *apiManager;

    @property (nonatomic, strong) NSArray *accounts;

    -(void)storeAccountWithAccessToken:(NSString *)token secret:(NSString *)secret;

    -(void)performReverseAuth:(id)sender inView:(UIView*)viewToDisplaySheet;

    -(void)_refreshTwitterAccounts;

  5. Now paste the following methods into your AppDelegate.m file

    -(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex;

    -(void)_refreshTwitterAccounts;

    -(void)_obtainAccessToAccountsWithBlock:(void (^)(BOOL))block;

    -(void)performReverseAuth:(id)sender inView:(UIView*)viewToDisplaySheet;

  6. In some initialization method of your file, or as of this example in: `application: didFinishLaunchingWithOptions' paste the following code:

    _store = [[ACAccountStore alloc] init];

    _apiManager = [[TWAPIManager alloc] init];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_refreshTwitterAccounts) name:ACAccountStoreDidChangeNotification object:nil];

  7. Remember to remove observer using the following code. Paste it in AppDelegate.m:

    -(void)dealloc{

    [[NSNotificationCenter defaultCenter] removeObserver:self];
    

    }

  8. Open your app-Info.plist file and add 2 string keys. Take their values from: https://apps.twitter.com/

    TWITTER_CONSUMER_KEY

    TWITTER_CONSUMER_SECRET

  9. In the View Controller that you want to use to implement twitter features, in the viewDidLoad method, add the following code:

    AppDelegate* appDelegate = [UIApplication sharedApplication].delegate;

    [appDelegate _refreshTwitterAccounts];

  10. OK, finally you are ready to start the whole machine. In the View Controller that you want to use to implement twitter features, create UIButton called _reverseAuthBtn and create an IBAction to it. Then in your IBAction paste the following code:

    AppDelegate* appDelegate = [UIApplication sharedApplication].delegate;

    [appDelegate performReverseAuth:sender inView:self.view];

Whew, I guess that's it! If I haven't forgotten about anything, you have got Twitter Reverse Oauth implementation, and if you want to use it in multiple view controllers, all you have to do is do steps 1-8, and then paste the code from the steps 9 and 10 into your view controller.

Best regards!

like image 27
Michael Avatar answered Nov 13 '22 13:11

Michael