7

我在我的一款 iOS 游戏中实现了整个 iOS Facebook 登录过程。在应用程序中,您可以使用电子邮件帐户或通过 Facebook 登录。如果用户使用电子邮件登录,我偶尔会展示一个视图,邀请用户将他的帐户与 Facebook 同步。

这是我用来确定是否应该向用户显示此视图的代码:

if (FBSession.activeSession.isOpen) {
    // Present the view
} else {
    // Go somewhere else
}

起初它似乎工作得很好,但事实证明,即使用户使用 FB 登录,FBSession.activeSession.isOpen 在某些时候也会返回 NO。

我的第一个猜测是 accessToken 过期了。我不确定这是否是一个好线索,因为我在我的应用程序中执行以下操作:didFinishLaunchingWithOptions: 方法(就像 Facebook 推荐的那样):

if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {
    // Yes, so just open the session (this won't display any UX).
    [self openSessionWithCompletionBlock:^{}];
}

所以现在我不知道如何重现或解决这个问题,知道吗?应用程序启动后令牌是否可能过期?就像用户在后台长时间保持应用程序一样?

4

1 回答 1

20

这只是 Facebook 的行为,每次启动应用程序时都需要“重新打开”会话,你的猜测是正确的,这是因为令牌状态,一个简单的解决方案是检查 [FBSession activeSession].isOpen 状态和如果它返回 NO 调用 openActiveSessionWithAllowLoginUI << Yes 相同的 facebook 方法,但检查它返回的所有状态。

如果会话先前已打开,则它使用存储的令牌重新打开会话,您不必担心登录 UI,因为它不会再次显示,因为会话先前已打开。

if (![FBSession activeSession].isOpen) {
   [self connectWithFacebook];
}

- (void) connectWithFacebook { 
       // The user has initiated a login, so call the openSession method
       // and show the login UI if necessary << Only if user has never 
       // logged in or ir requesting new permissions.
       PPAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
       [appDelegate openSessionWithAllowLoginUI:YES];
}

在应用程序委托中

- (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI
{
    NSArray *permissions = @[@"any_READ_permision_you_may_need"];

    return [FBSession openActiveSessionWithReadPermissions:permissions
                                              allowLoginUI:allowLoginUI
                                         completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
                                              if (error) {
                                                  NSLog (@"Handle error %@", error.localizedDescription);
                                              } else {
                                                  [self checkSessionState:state];
                                              }
                                         }];
}

- (void) checkSessionState:(FBState)state {
    switch (state) {
        case FBSessionStateOpen:
            break;
        case FBSessionStateCreated:
            break;
        case FBSessionStateCreatedOpening:
            break;
        case FBSessionStateCreatedTokenLoaded:
            break;
        case FBSessionStateOpenTokenExtended:
            // I think this is the state that is calling
            break;
        case FBSessionStateClosed:
            break;
        case FBSessionStateClosedLoginFailed:
            break;
        default:
            break;
    }
}

这是一个快速修复并且有效,您也可以通过关闭会话来重现它,但无需使用清除令牌缓存[[FBSession activeSession] close]您甚至可以更改令牌缓存策略,如此处所述http://developers.facebook.com/docs/howtos/令牌缓存-ios-sdk/

于 2013-04-18T18:13:42.237 回答