连续启动时打开FBSession(适用于SDK 3.0的FB SDK)

Ahm*_*gle 11 facebook ios facebook-ios-sdk

我正在尝试集成适用于iOS的新Facebook SDK,并且在理解某些概念时遇到了问题.

  1. 我使用[FBSession sessionOpenWithPermissions:...]auth对话框进行身份验证,然后我返回应用程序.验证成功.

  2. 然后关闭应用程序,重新启动.[[FBSession activeSession] accessToken]成功返回以前保存的令牌.

  3. 但是,与此同时,[[FBSession activeSession] isOpen]回报NO.(这意味着会话尚未准备好使用.)

  4. 此时,[[FBSession activeSession] state]正是FBSessionStateCreatedTokenLoaded在这个时候.这里的教程使用isOpencall来验证活动会话是否已加载并使用令牌打开.

那么我们打算如何在不将用户重定向到auth对话框的情况下打开加载令牌的会话呢?

提示:

FBSessionState枚举中,因为FBSessionStateOpen它说:

打开会话状态,指示用户已登录或缓存令牌可用.

但是FBSessionStateCreatedTokenLoaded被描述为:

两个初始会话状态之一,指示已加载缓存的令牌; 当会话处于此状态时,对open*的调用将导致打开会话,而无需UX或app切换

你能帮我理解这些会话过渡吗?

idS*_*tar 31

我包括一个我编写的Facebook实用程序类,它有助于理解登录状态,因为我在自己的设置UI中向用户公开了"登录"/"未登录"消息,此外还使用了实际的"FBLoginView"组件,当允许用户切换授权状态时.

下面的代码也可以通过这个要点获得.

我可能没有FBSessionState在我的switch语句中正确解释所有类型,但到目前为止,它在我测试过的情况下很好用(我只是把它放在一起).

其他人提到的关键是,有时候你有一个不能立即使用的缓存授权令牌,但是如果你open对它进行Facebook 调用,你可以让它重复使用(刷新).此公开调用在幕后工作,不会触发任何UI/jarring OAuth窗口/应用程序切换(如果您有缓存的令牌).

请参阅我在方法中的评论isLoggedInAfterOpenAttempt.请注意我如何检查状态,FBSessionStateCreatedTokenLoaded然后才进行调用

-openWithCompletionHandler:^(FBSession *session, FBSessionState status, NSError *error).

关于这个类的其他花絮:

  • 我在这里有一个属性来缓存登录用户,其类型符合协议FBGraphUser.但是,它并未在此处演示的任何登录方法中使用.
  • Facebook SDK 3.0 for iOS示例代码建议构建您自己的类来保持和管理这些类型的操作,如果您有的不仅仅是一个简单的应用程序.下面这个类是我的应用程序的想法的开始.
  • 你可以用NSLog替换我的'log4Info'和'log4Debug'宏来实现这个功能.
#import "UWFacebookService.h"

@implementation UWFacebookService

// Static
static const int ddLogLevel = LOG_LEVEL_DEBUG;

// Strong
@synthesize facebookGraphUser = _facebookGraphUser;


#pragma mark - Inquiries

- (BOOL)isSessionStateEffectivelyLoggedIn:(FBSessionState)state {
    BOOL effectivelyLoggedIn;

    switch (state) {
        case FBSessionStateOpen:
            log4Info(@"Facebook session state: FBSessionStateOpen");
            effectivelyLoggedIn = YES;
            break;
        case FBSessionStateCreatedTokenLoaded:
            log4Info(@"Facebook session state: FBSessionStateCreatedTokenLoaded");
            effectivelyLoggedIn = YES;
            break;
        case FBSessionStateOpenTokenExtended:
            log4Info(@"Facebook session state: FBSessionStateOpenTokenExtended");
            effectivelyLoggedIn = YES;
            break;
        default:
            log4Info(@"Facebook session state: not of one of the open or openable types.");
            effectivelyLoggedIn = NO;
            break;
    }

    return effectivelyLoggedIn;
}

/**
* Determines if the Facebook session has an authorized state. It might still need to be opened if it is a cached
* token, but the purpose of this call is to determine if the user is authorized at least that they will not be
* explicitly asked anything.
*/
- (BOOL)isLoggedIn {
    FBSession *activeSession = [FBSession activeSession];
    FBSessionState state = activeSession.state;
    BOOL isLoggedIn = activeSession && [self isSessionStateEffectivelyLoggedIn:state];

    log4Info(@"Facebook active session state: %d; logged in conclusion: %@", state, (isLoggedIn ? @"YES" : @"NO"));

    return isLoggedIn;
}


/**
* Attempts to silently open the Facebook session if we have a valid token loaded (that perhaps needs a behind the scenes refresh).
* After that attempt, we defer to the basic concept of the session being in one of the valid authorized states.
*/
- (BOOL)isLoggedInAfterOpenAttempt {
    log4Debug(@"FBSession.activeSession: %@", FBSession.activeSession);

    // If we don't have a cached token, a call to open here would cause UX for login to
    // occur; we don't want that to happen unless the user clicks the login button over in Settings, and so
    // we check here to make sure we have a token before calling open
    if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {
        log4Info(@"We have a cached token, so we're going to re-establish the login for the user.");
        // Even though we had a cached token, we need to login to make the session usable:
        [FBSession.activeSession openWithCompletionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
            log4Info(@"Finished opening login session, with state: %d", status);
        }];
    }
    else {
        log4Info(@"Active session wasn't in state 'FBSessionStateCreatedTokenLoaded'. It has state: %d", FBSession.activeSession.state);
    }

    return [self isLoggedIn];
}

@end


Dan*_*iel 5

这意味着当您有令牌保存(缓存)或已经可用时,Facebook iOS库仍然要求您使用open方法重新初始化会话.

如果它可以重用现有令牌(这是你的情况),那么这样做将会触发用户体验(用户体验 - 即应用程序切换或Facebook登录弹出窗口).

用户的印象是他从未退出,但在应用程序中发生的事情是您正在联系Facebook以重新打开会话.

这样设计的原因是因为在令牌可用但已过期的情况下,Facebook库会告诉您 - "嘿令牌已过期,请考虑自己退出,除非您现在获得新令牌."

希望有所帮助.