Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the Facebook iOS SDK require the user to authenticate every time they use the app?

As described in the README for facebook-ios-sdk, my app calls Facebook#authorize:delegate: before performing any API calls.

This method requires the user to authenticate (either in the Facebook app or in Safari) and then drops control back to my iPhone app. The problem is it asks the user to authenticate every time I call the method. If they've already granted permission to my app, they get a message saying that the app is already authorized and they have to press Okay to go back to my app. It doesn't look very professional.

So I have two questions:

  1. Does the user always have to reauthorize in order to make Facebook calls? I always thought it would save the access token somewhere, maybe in the user defaults, so that you wouldn't need to reauthorize.

  2. If the user doesn't have to reauthorize every time, is there a way to check if my app already has permission, so the user doesn't have to see that message and press Okay?

like image 332
Bill Avatar asked Apr 06 '11 19:04

Bill


2 Answers

It's unfortunate that the Facebook SDK doesn't automatically handle it for us. Aside from building it into the SDK yourself, the easiest way is as such:

Each time you allocate _facebook:

_facebook = [[Facebook alloc] initWithAppId:@"SuperDuperAppID"];
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
NSString *accessToken = [prefs stringForKey:@"facebook-accessToken"];
NSString *expirationDate = [prefs stringForKey:@"facebook-expirationDate"];
_facebook.accessToken = accessToken;
_facebook.expirationDate = expirationDate;

If you've never saved anything in the NSUserDefaults, then nil values will be set. Nothing's happened. Otherwise, true values will be set, and [_facebook isSessionValid]; should return TRUE, indicating good values. Go ahead and make Facebook SDK calls as if they are logged in (which they are). If false, then call

[facebook authorize:permissions delegate:self]; 

as usual.

Then make sure to support the following Facebook delegate method:

- (void)fbDidLogin {
NSString *accessToken = _facebook.accessToken;
NSString *expirationDate = _facebook.expirationDate;
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
[prefs setObject:accessToken forKey:@"facebook-accessToken"];
[prefs expirationDate forKey:@"facebook-expirationDate"];
[prefs synchronize];
}

I use this code in my app, and it works perfectly. I did this from memory, so I apologize if it doesn't work on copy-and-paste. There might be a mistype somewhere, plus improper memory management. Don't forget that access tokens expire unless you get offline permission. In any case the code above handles everything.

like image 168
Daniel Amitay Avatar answered Nov 05 '22 23:11

Daniel Amitay


The problem is it asks the user to authenticate every time I call the method. If they've already granted permission to my app, they get a message saying that the app is already authorized and they have to press Okay to go back to my app.

1) Does the user always have to reauthorize in order to make Facebook calls? I always thought it would save the access token somewhere, maybe in the user defaults, so that you wouldn't need to reauthorize.

The cause of having to go through the sign on process every time is that, after successfully signing on the first time, the Facebook SDK doesn't save the access token in a persistent manner.

2) If the user doesn't have to reauthorize every time, is there a way to check if my app already has permission, so the user doesn't have to see that message and press Okay?

The fact that the Facebook SDK doesn't save the access token doesn't mean you can't do it yourself. The following code ilustrates how to save/retrieve the access token from the NSUserDefaults.

-(void)login {
    // on login, use the stored access token and see if it still works
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    facebook.accessToken = [defaults objectForKey:ACCESS_TOKEN_KEY];
    facebook.expirationDate = [defaults objectForKey:EXPIRATION_DATE_KEY];

    // only authorize if the access token isn't valid
    // if it *is* valid, no need to authenticate. just move on
    if (![facebook isSessionValid]) {
        NSArray * permissions = [NSArray arrayWithObjects:@"read_stream", @"offline_access", @"email", nil];
        [facebook authorize:permissions delegate:self];
    }
}

/**
 * Called when the user has logged in successfully.
 */
- (void)fbDidLogin {
    // store the access token and expiration date to the user defaults
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:facebook.accessToken forKey:ACCESS_TOKEN_KEY];
    [defaults setObject:facebook.expirationDate forKey:EXPIRATION_DATE_KEY];
    [defaults synchronize];
}
like image 28
albertamg Avatar answered Nov 06 '22 00:11

albertamg