ios6 facebook integration login always FBSessionSt

2019-02-08 09:09发布

问题:

this question is very similar to Facebook SDK for iOS , on iOS 4.0 device, but as I cannot make comments there, I open a new question. I think the questions are not the same:

When trying to update the facebook integration of my app to facebook 3.1 I am not getting the facebook session to open the sessionStateChanged Callback always ends up in FBSessionStateClosedLoginFailed. in my setup I have the callback in my appdelegate

- (BOOL)application:(UIApplication *)application 
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation {
    // attempt to extract a token from the url
    //    return [self.session handleOpenURL:url]; 
    return [FBSession.activeSession handleOpenURL:url];
}

but it is never called! shouldn't it get called? I followed the facebook documentation and call

- (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI {
    NSArray *permissions = [NSArray arrayWithObjects:@"publish_actions", nil];
    return [FBSession openActiveSessionWithPublishPermissions:permissions
                                              defaultAudience:FBSessionDefaultAudienceFriends
                                              allowLoginUI:allowLoginUI
                                         completionHandler:^(FBSession *session,
                                                             FBSessionState state,
                                                             NSError *error) {
                                             [self sessionStateChanged:session
                                                                 state:state
                                                                 error:error];
                                         }];
}

I also tried

openActiveSessionWithReadPermissions with nil for the permissions as in the facebook tutorial example with the intention to reauthorize for the publish_actions permission later. same result: FBSessionStateClosedLoginFailed again.

I even tried calling

ACAccountStore *accountStore;
    ACAccountType *accountTypeFB;
    if ((accountStore = [[ACAccountStore alloc] init]) &&
        (accountTypeFB = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook] ) ){

        NSArray *fbAccounts = [accountStore accountsWithAccountType:accountTypeFB];
        id account;
        if (fbAccounts && [fbAccounts count] > 0 &&
            (account = [fbAccounts objectAtIndex:0])){

            [accountStore renewCredentialsForAccount:account completion:^(ACAccountCredentialRenewResult renewResult, NSError *error) {
                //we don't actually need to inspect renewResult or error.
                if (error){

                }
            }];
        }
    }

before trying to open the session, but I never get it open on my ios6 device (iphone 4s). in the app I am asked for the permission, but then nothing goes on because the session is always having the state FBSessionStateClosedLoginFailed! my callback for the session state is

- (void)sessionStateChanged:(FBSession *)session
                      state:(FBSessionState) state
                      error:(NSError *)error
{
    switch (state) {
        case FBSessionStateOpen:
            if (!error) {
                // We have a valid session
                NSLog(@"User session found");
            }
            break;
        case FBSessionStateClosed:
            NSLog(@"FBSessionStateClosed");
        case FBSessionStateClosedLoginFailed:
            NSLog(@"FBSessionStateClosedLoginFailed");
            [FBSession.activeSession closeAndClearTokenInformation];
            break;
        default:
            break;
    }

    [[NSNotificationCenter defaultCenter]
     postNotificationName:FBSessionStateChangedNotification
     object:session];

    if (error) {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"facebook Hinweis"
                                                        message:@"facebook Login nicht möglich, bitte versuchen Sie es erneut."
                                                       delegate:nil
                                              cancelButtonTitle:@"OK"
                                              otherButtonTitles:nil];
        [alert show];
        NSLog(@"Facebook session error: %@", error.localizedDescription);
    }
}

with the facebook 3.0 on ios 5 I never had an issue so my facebook app is set up correctly. I would really appreciate any help wchich enables me to just open the facebook session, did not think to run into these problems with facebook 3.1 and the docs are not helping me at this point, thx

回答1:

I had the same problem, and it was because I forgot to implement

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
    return [FBSession.activeSession handleOpenURL:url];
}

in my AppDelegate



回答2:

While JohnG's answer is correct, that particular delegate method has now been deprecated. The correct delegate method to use is this:

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
    return [FBSession.activeSession handleOpenURL:url];
}

Placing that in my application delegate solved the issue for me. Without this, the iOS 6.0 native login would work but the Facebook app login would fail.



回答3:

I had the same problem. If the user hadn't a Facebook account configured in the System Preferences the Facebook login dialog appeared and everything worked fine. But if the user had an account configured in the device I was always having a FBSessionStateClosedLoginFailed error.

It has nothing to do with handleOpenURL:url because in the "native login flow" for iOS 6 or greater there is no fast-app-change. So your app never goes to background and the URL redirection is not needed.

The problem was solved configuring the Facebook app. You need to enable the "Native iOS login" section and put the bundle ID of your app. If your app is not already in the Apple Store I'm afraid you need to set the sandbox mode to ON. Once your app is published in the Apple Store I think you need to put the sandbox mode to OFF and set the Apple Store ID in the Facebook configuration.



回答4:

Even i can't comment so writing it as answer . I am not sure , let me analyze potential reasons 1) you said: "but it is never called! shouldn't it get called?" -- for

- (BOOL)application:(UIApplication *)application 
        openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication
     annotation:(id)annotation

to get called , in the info.plist file , url scheme should be set properly i.e go to URL types-->Item0-->URL Schemes--->Item 0 the value here should be fbAPPID i.e fb append with your actual facebookappID [FacebookAppID could also be present in the info.plist or hard coded in code].

2)You said: "sessionStateChanged Callback always ends up in FBSessionStateClosedLoginFailed"

In the sessionStateChanged switch method check the state of session and if it created or createdTokenLoaded then try to open the session.

Note:[FBSession openActiveSessionWithPublishPermissions ....] which is a static method will create a new session and is set to FBSession.activeSession where as openWithCompletionHandler is an instance method which can work only if the session is already created .

    case FBSessionStateCreated:
    case FBSessionStateCreatedTokenLoaded:{
        [session openWithCompletionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
            //handle the updating of views according to the sate of session 
        }];
        break;


回答5:

I agree with JohnG, with the additional caveat of:

Note that if you have multiple cases inside of handleOpenURL:, you can filter for:

if ([sourceApplication isEqualToString:@"com.facebook.facebook"] ||
    [sourceApplication isEqualToString:@"com.facebook.Facebook"]){
  //Do Stuff
}

It's weird, but I was able to replicate on multiple devices the sourceApplication coming back as "Facebook" and "facebook".



回答6:

On FB SDK 3.5, You can kill the token with this:

    [[FBSessionTokenCachingStrategy defaultInstance] clearToken];