Facebook iOS SDK Not Calling Completion Handler

亡梦爱人 提交于 2019-12-11 03:36:22

问题


Problem:

Using the FB SDK and the method openActiveSessionWithReadPermissions, the completion handler doesn't appear to get called when the app is reopened from Facebook web or Facebook app and I get this error output:

FBSDKLog: FBSession INVALID transition from FBSessionStateCreated to FBSessionStateClosed FBSDKLog: FBSession transition from FBSessionStateCreated to FBSessionStateCreatedOpening

Context

  • Using Facebook SDK 3.2.1
  • App is built for iOS 5.0+
  • Using xCode 4.6.1
  • Testing on Simulator iOS 5.1
  • Testing on iPhone 4S, running iOS 6.1.2 (not using 6.0 social framework as want to test implementation for 5.0+)
  • Updating an app that was originally built for iOS 3.0 and using an old version of sharekit, but has now been updated for ARC and the share kit implementation I believe has all been commented out - hoping the issue is not a conflict with a old share kit function, can't fin any within the code

Steps taken to resolve

Searched throughout Stack Overflow, found similar issues mentioned but not a solution

  • ios6 facebook integration login always FBSessionStateClosedLoginFailed never opens (i already have bool:application implemented)
  • Facebook iOS SDK 3.0 - session not open
  • Facebook SDK 3.1 - Error validating access token
  • Have the correct app bundle in the FB settings panel
  • Have the correct Facebook app ID is the plist
  • Have FB logging turned on FBSettings setLoggingBehavior

Specifics:

These are the steps I took to implement Facebook connectivity within the app.

  • The first step I took was walking through the Facebook tutorial at: https://developers.facebook.com/docs/tutorials/ios-sdk-tutorial/. I got the first part, the authentication part working as expected (I built a separate app as instructed by the tutorial.)
  • I then took the same steps within the tutorial in the app I'm updating, this did not work
  • I then followed the instructions on https://developers.facebook.com/docs/howtos/login-with-facebook-using-ios-sdk/ (which are very similar to the tutorial)
  • Again I ran into issues
  • Then spent a lot of time searching for solution, could not find one

Highlevel steps in code:

  • I have my FB methods set up in AppDelegate
  • In a specific view controller I have a button that calls the openSessionWithAllowLoginUI method to start the login process

Code

AppDelegate.m

- (void)applicationDidFinishLaunching:(UIApplication *)application 
{   
// set up facebook logging
    [FBSettings setLoggingBehavior:[NSSet setWithObjects:FBLoggingBehaviorFBRequests, FBLoggingBehaviorFBURLConnections, FBLoggingBehaviorAccessTokens, FBLoggingBehaviorSessionStateTransitions, nil]];

    // Call the ACAccountStore method renewCredentialsForAccount, which will update the OS's understanding of the token state
    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){

                }
            }];
        }
    }

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // We need to properly handle activation of the application with regards to Facebook Login
    // (e.g., returning from iOS 6.0 Login Dialog or from fast app switching).
    NSLog(@"Calling app did become active");
    [FBSession.activeSession handleDidBecomeActive];
}

/*
 * Callback for session changes.
 */
- (void)sessionStateChanged:(FBSession *)session
                      state:(FBSessionState) state
                      error:(NSError *)error
{
    NSLog(@"Session State Changed");

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

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

    if (error) {
        UIAlertView *alertView = [[UIAlertView alloc]
                                  initWithTitle:@"Error"
                                  message:error.localizedDescription
                                  delegate:nil
                                  cancelButtonTitle:@"OK"
                                  otherButtonTitles:nil];
        [alertView show];
    }
}

/*
 * Opens a Facebook session and optionally shows the login UX.
 */
- (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI {
    NSLog(@"Openning session with Facebook");
    return [FBSession openActiveSessionWithReadPermissions:nil
                                              allowLoginUI:allowLoginUI
                                         completionHandler:^(FBSession *session,
                                                             FBSessionState state,
                                                             NSError *error) {
                                             [self sessionStateChanged:session
                                                                 state:state
                                                                 error:error];
                                         }];
}


/*
 * If we have a valid session at the time of openURL call, we handle
 * Facebook transitions by passing the url argument to handleOpenURL
 */
- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation {
    // attempt to extract a token from the url
    NSLog(@"Calling open URL");
    return [FBSession.activeSession handleOpenURL:url];
}

- (void) closeSession {
    NSLog(@"Clossing Facebook Sessions");
    [FBSession.activeSession closeAndClearTokenInformation];
}

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
    NSLog(@"handleOpenUrl Called");
    return [FBSession.activeSession handleOpenURL:url];

}

View Controller with button

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.

    // Register for Facebook change notification
    [[NSNotificationCenter defaultCenter]
     addObserver:self
     selector:@selector(sessionStateChanged:)
     name:FBSessionStateChangedNotification
     object:nil];
}

- (IBAction)login:(id)sender {
    ATIAppDelegate *myAppDelegate = (ATIAppDelegate *)[[UIApplication sharedApplication]delegate];
     [myAppDelegate openSessionWithAllowLoginUI:YES];
}

What I think the issue could be?

  • It seems like it may be something with the tokens?
  • Or maybe the notification center?
  • Note that during testing I've been going and revoking access of the Facebook app to my account and then trying to login again to the app, I see these has caused issues with other users

回答1:


Okay I figured it out - the issue was nothing to do with FB itself, the app (I'm working on updating someone else's code) had a setting in the .plist - 'Application does not run in background' set to true.

Meaning that once the app was relaunched from the Facebook app or Facebook mobile site it wasn't prepared to handle the next step.




回答2:


If you don't want the app to run in the background, you can bind to the FBSDKApplicationDelegate in your AppDelegate like so:

import UIKit
import FBSDKLoginKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?


    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
    }

    func applicationWillResignActive(_ application: UIApplication) {
        FBSDKAppEvents.activateApp()
    }

    func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
        return FBSDKApplicationDelegate.sharedInstance().application(application, open: url, sourceApplication: sourceApplication, annotation: annotation)
    }
}

https://forums.developer.apple.com/thread/50332 http://ashishkakkad.com/tag/fbsdkapplicationdelegate/



来源:https://stackoverflow.com/questions/15775160/facebook-ios-sdk-not-calling-completion-handler

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!