【问题标题】:Facebook iOS SDK Not Calling Completion HandlerFacebook iOS SDK 未调用完成处理程序
【发布时间】:2013-03-24 09:35:24
【问题描述】:

问题:

使用 FB SDK 和 openActiveSessionWithReadPermissions 方法,当应用从 Facebook 网络或 Facebook 应用重新打开时,完成处理程序似乎没有被调用,并且我收到以下错误输出:

FBSDKLog: FBSession INVALID 从 FBSessionStateCreated 转换到 FBSessionStateClosed FBSDKLog: FBSession 从 FBSessionStateCreated 过渡到 FBSessionStateCreatedOpening

上下文

  • 使用 Facebook SDK 3.2.1
  • 应用专为 iOS 5.0+ 构建
  • 使用 xCode 4.6.1
  • 在模拟器 iOS 5.1 上测试
  • 在 iPhone 4S 上测试,运行 iOS 6.1.2(不使用 6.0 社交框架,因为想要测试 5.0+ 的实现)
  • 更新最初为 iOS 3.0 构建并使用旧版本 sharekit 的应用程序,但现在已针对 ARC 进行了更新,并且我认为共享工具包实现已全部被注释掉 - 希望问题不与旧的共享套件功能,无法在代码中找到任何功能

解决步骤

在整个 Stack Overflow 中搜索,发现提到的类似问题,但不是解决方案

具体说明:

这些是我在应用中实现 Facebook 连接所采取的步骤。

代码中的高级步骤:

  • 我在 AppDelegate 中设置了我的 FB 方法
  • 在特定的视图控制器中,我有一个按钮,它调用 openSessionWithAllowLoginUI 方法来启动登录过程

代码

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];

}

使用按钮查看控制器

- (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];
}

我认为问题可能是什么?

  • 好像是令牌的问题?
  • 或者通知中心?
  • 请注意,在测试期间,我一直在撤销 Facebook 应用程序对我的帐户的访问权限,然后尝试再次登录该应用程序,我发现这导致其他用户出现问题李>

【问题讨论】:

  • 好吧,我想通了 - 问题与 FB 本身无关,应用程序(我正在更新其他人的代码)在 .plist 中有一个设置 - '应用程序没有运行在后台'设置为真。这意味着一旦从 Facebook 应用程序或 Facebook 移动网站重新启动该应用程序,它就无法处理下一步。
  • 我会在 stackoverflow 让我在几个小时后添加这个作为答案。
  • 嘿,drc,我有同样的错误,但我在 .plist 中的任何地方都没有看到“应用程序不在后台运行”。这是应用程序主 .plist 还是您的应用程序具有的附加 .plist?
  • 它在主 .plist 中
  • 我从 plist 添加了一张图片

标签: ios facebook facebook-ios-sdk


【解决方案1】:

好的,我想通了 - 问题与 FB 本身无关,应用程序(我正在更新其他人的代码)在 .plist 中有一个设置 - '应用程序不在后台运行'设置为真的。

这意味着一旦从 Facebook 应用或 Facebook 移动网站重新启动该应用,它就没有准备好处理下一步。

【讨论】:

    【解决方案2】:

    如果您不希望应用在后台运行,您可以像这样绑定到 AppDelegate 中的FBSDKApplicationDelegate

    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/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-17
      • 2014-08-16
      • 2015-12-18
      • 1970-01-01
      • 1970-01-01
      • 2021-03-18
      • 2013-02-18
      相关资源
      最近更新 更多