FacebookSDK presents login UI twice

2019-04-10 09:56发布

Using iOS 6 with the FacebookSDK splits the requests for read and publish permissions into two separate calls. I'm not sure why there's any benefit to this, but it seems to require presenting the user with the Facebook UI twice the first time thru.

In my app, I don't request anything from Facebook until a user chooses to use Facebook, in which case they are first presented with the UI to get read permissions, then again to get publish permissions. Control switches from my app to facebook (for read) back to my app and then immediately back to facebook (for publish) then back to my app.

This is an awful user experience, especially since the facebook screen with the "Okay" looks the same to the user. (Why am I pressing Okay twice?)

My code, in a nutshell is:

Check for a valid FBSession.activeSession
if not open call FBSession openActiveSessionWithReadPermissions
if successful call FBSession.activeSession reauthorizeWithPublishPermissions
then publish post

The code works, but the user experience is lousy. Am I missing something?

1条回答
劫难
2楼-- · 2019-04-10 10:14

My understanding is that iOS 6 is requiring the double login for their ACAccountStore support, so the Facebook login tutorial implies that you should do this for all cases. Switching the app twice is a bad user experience and I think I have come up with a work around.

Firstly, for older iOS's (e.g iOS 5.0) can you just use openActiveSessionWithPublishPermissions: and do the read and publish permissions in one swoop. Secondly, this same call works if the user has never logged into Facebook from the Device Settings. Therefore, the following code seems to work like this:

  • If user has logged into Facebook from Device Settings: One dialog for read and one dialog for publish.
  • Else if user has Facebook app installed: switch to FB app once, and get 2 prompts in a row.
  • Otherwise: switch to Safari once, and get 2 prompts in a row

I tested this code on an iOS6 and iOS5 device, using Facebook SDK 3.2.1

- (BOOL)hasFacebookInDeviceSettings
{
    ACAccountStore *accountStore = [[ACAccountStore alloc] init];
    ACAccountType *accountTypeFB = [accountStore accountTypeWithAccountTypeIdentifier:@"com.apple.facebook"];
    BOOL hasFacebookBuiltinAccount = (accountTypeFB != nil);
    return hasFacebookBuiltinAccount;
}

- (BOOL)hasLoggedInToFacebookInDeviceSettings
{
    if (![self hasFacebookInDeviceSettings]) {
        return NO;
    }
    BOOL result = [SLComposeViewController isAvailableForServiceType:SLServiceTypeFacebook];
    return result;
}

- (void)openFacebookSessionWithAllowLoginUI:(BOOL)allowLoginUI
{
    if (![self hasLoggedInToFacebookInDeviceSettings]) {
        // Simpler if we don't have the built in account
        [FBSession openActiveSessionWithPublishPermissions:@[@"publish_actions"]
                                           defaultAudience:FBSessionDefaultAudienceFriends
                                              allowLoginUI:allowLoginUI
                                         completionHandler:^(FBSession *session,
                                                             FBSessionState state,
                                                             NSError *error) {
                                             [self facebookSessionStateChanged:session
                                                                         state:state
                                                                         error:error];
                                         }];
    }
    else if (!FBSession.activeSession.isOpen) {
        __block BOOL recursion = NO;
        [FBSession openActiveSessionWithReadPermissions:nil
                                           allowLoginUI:allowLoginUI
                                      completionHandler:^(FBSession *session,
                                                          FBSessionState state,
                                                          NSError *error) {
                                          if (recursion) {
                                              return;
                                          }
                                          recursion = YES;
                                          if (error || !FBSession.activeSession.isOpen) {
                                              [self facebookSessionStateChanged:session
                                                                          state:state
                                                                          error:error];
                                          }
                                          else {
                                              assert(FBSession.activeSession.isOpen);
                                              if ([FBSession.activeSession.permissions indexOfObject:@"publish_actions"] == NSNotFound) {
                                                  [FBSession.activeSession requestNewPublishPermissions:@[@"publish_actions"]
                                                                                        defaultAudience:FBSessionDefaultAudienceFriends
                                                                                      completionHandler:^(FBSession *session,
                                                                                                          NSError *error) {
                                                                                          [self facebookSessionStateChanged:session
                                                                                                                      state:FBSession.activeSession.state
                                                                                                                      error:error];
                                                                                      }];
                                              }
                                          }
                                      }];
    }
}

hasFacebookInDeviceSettings tells you if this device even supports Facebook from the settings (i.e. this is iOS6+).

hasLoggedInToFacebookInDeviceSettings tells you if the user has signed into to Facebook from the iOS6 Facebook device settings.

You'll need to create your own facebookSessionStateChanged: and other code, as described in the login tutorial

查看更多
登录 后发表回答