pck.atl
pck.atl

Reputation: 133

Facebook iOS SDK: authorize with permissions requires 2 attempts

I have an app that still uses the deprecated Facebook class to connect with Facebook. If I authorize with no extended permissions, everything works fine. But if I do include permissions, the first round trip to authorize always fails (even though it gets a valid token!). Am I missing a step?

Here's the code to initiate Facebook authorization for the app

- (IBAction) doConnect:(id)sender
{
    NSArray* permissions = [NSArray arrayWithObjects:
                            @"email",@"publish_actions",nil];
    [self.facebook authorize:permissions];
}

Here's the code that gets invoked after the user has granted permissions and control returns to my app. The url always includes a nice looking token, even the first time through.

// handle the incoming url from app switching
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
    return [self.facebook handleOpenURL:url];
}

And here's the FBSessionDelegate method that gets invoked after a successful connect. Even though the url above contained a token, it's gone the first time we get here. But if I invoke the doConnect method above, the token will be present when we get here.

// FBSessionDelegate
- (void)fbDidLogin
{
    if( [self.facebook accessToken] == nil )
    {
        NSLog(@"Had an access token above, but not now!");

        // If I reinvade the doConnect: method again, it will work!!!
    }
    // ...

}

Looking deep in the sdk code in FBSession.m, it seems that the requested permissions haven't been associated with the new token first time through, causing the session to ignore the new token. First time through, cachedPermissions is always an empty list

    // get the cached permissions, and do a subset check
    NSArray *cachedPermissions = [tokenInfo objectForKey:FBTokenInformationPermissionsKey];
    BOOL isSubset = [FBSession areRequiredPermissions:permissions
                                 aSubsetOfPermissions:cachedPermissions];

Upvotes: 4

Views: 4490

Answers (3)

Amit Saxena
Amit Saxena

Reputation: 596

we can authorise user in single request. It does not need two times attempt. To achieve this what we need do is "We need to ask for publish permission first". Call the below method

let fbLoginMngr =  FBSDKLoginManager();
fbLoginMngr.logOut()
fbLoginMngr.logInWithPublishPermissions

it will ask first profile details then asks for requested publish permission. Once we get a call back we query to Graph api to extract the profile data like below.

let fbRequest = FBSDKGraphRequest(graphPath:"me",    parameters:self.FB_REQ_PARAMS);
                fbRequest.startWithCompletionHandler { (connection : FBSDKGraphRequestConnection!, result : AnyObject!, error : NSError!) -> Void in
                    if error == nil {
                        debugPrint(result)
                    } else {
                        handleError(error)
                    }
                }

Upvotes: 0

Nur Iman Izam
Nur Iman Izam

Reputation: 1613

For Facebook SDK 3.1, use [FBSession activeSession]'s

reauthorizeWithPublishPermissions: defaultAudience:completionHandler:

For Facebook SDK 3.2, use [FBSession activeSession]'s

requestNewPublishPermissions: defaultAudience:completionHandler:

Upvotes: 0

C Abernathy
C Abernathy

Reputation: 5513

You are asking for two types of permissions, a read type (email) and a write type (publish_actions).

You should be using the latest Facebook SDK, v3.1.1 and you'll have to split up read and writes separately - especially if you wish to support iOS6. You can only ask for reads initially. See the note in https://developers.facebook.com/docs/tutorial/iossdk/upgrading-from-3.0-to-3.1/ and the section on asking for read and writes separately.

Upvotes: 3

Related Questions