ios 在连续启动中打开 FBSession(用于 SDK 3.0 的 FB SDK)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11891834/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 19:40:15  来源:igfitidea点击:

Opening FBSession in consecutive launches (FB SDK for SDK 3.0)

iosfacebookfacebook-ios-sdk

提问by AhmetB - Google

I am trying to integrate the new Facebook SDK for iOS and had a problem understanding some concepts.

我正在尝试为 iOS 集成新的 Facebook SDK,但在理解某些概念时遇到了问题。

  1. I authenticate using [FBSession sessionOpenWithPermissions:...]auth dialog comes up and I return the app. Auth successful.

  2. Then shut down the app, relaunch again. [[FBSession activeSession] accessToken]successfully returns previously saved token.

  3. However, at the same time, [[FBSession activeSession] isOpen]returns NO. (This means session is not ready for use.)

  4. Also, [[FBSession activeSession] state]is FBSessionStateCreatedTokenLoadedat this time. Tutorial hereuses isOpencall to verify active session is loaded and opened with token.

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

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

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

  4. 还有,[[FBSession activeSession] state]就是FBSessionStateCreatedTokenLoaded在这个时候。此处的教程使用isOpen调用来验证活动会话是否已加载并使用令牌打开。

So what do we call to open the token-loaded session without redirecting user to auth dialog?

那么我们调用什么来打开加载令牌的会话而不将用户重定向到身份验证对话框?

Hints:

提示:

In FBSessionStateenum, for FBSessionStateOpenit says:

FBSessionState枚举中,因为FBSessionStateOpen它说:

Open session state indicating user has logged in or a cached token is available.

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

However FBSessionStateCreatedTokenLoadedis described as:

然而FBSessionStateCreatedTokenLoaded被描述为:

One of two initial session states indicating that a cached token was loaded; when a session is in this state, a call to open* will result in an open session, without UX or app-switching

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

Could you please help me figure out understanding these session transitions?

你能帮我弄清楚这些会话转换吗?

回答by idStar

I'm including a Facebook utility class I wrote that helps with understanding login state, because I expose a "logged in" / "not logged in" message to the user in my own Settings UI, in addition to using the actual 'FBLoginView' component when it comes time to allow the user to toggle authorization state.

我包含了一个我编写的有助于理解登录状态的 Facebook 实用程序类,因为除了使用实际的“FBLoginView”之外,我还在自己的设置 UI 中向用户公开了“已登录”/“未登录”消息组件何时允许用户切换授权状态。

The code below is also available via this gist.

下面的代码也可以通过这个gist 获得

I may not have interpreted all the FBSessionStatetypes correctly in my switch statement, but thus far, it's served me well in the cases I've tested (I've just put this together).

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

The key thing to note, that others have alluded to, is that sometimes you have a cached authorization token that you can't use immediately, but if you make a Facebook opencall on it, you can get it to be reusable (refreshed). This open call works behind the scenes, without triggering any UI / jarring OAuth window/app switching (if you have a cached token).

需要注意的关键是,其他人已经提到,有时您有一个无法立即使用的缓存授权令牌,但是如果您对其进行 Facebookopen调用,您可以使其可重复使用(刷新)。这个公开调用在幕后工作,不会触发任何 UI/不和谐的 OAuth 窗口/应用程序切换(如果您有缓存的令牌)。

See my comments in the method isLoggedInAfterOpenAttempt. Note how I check for the state to be FBSessionStateCreatedTokenLoadedand only then, make the call to

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

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

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

Other tidbits about this class:

关于这个类的其他花絮:

  • I have a property here to cache the logged in user, of type conforming to protocol FBGraphUser. It's not used in any of the login methods demonstrated here, though.
  • The Facebook SDK 3.0 for iOS sample code suggests constructing your own class to hold on to and manage these kinds of operations, if you have anything more than a trivial app. This class of mine below is the beginnings of that idea for my app.
  • You can replace my 'log4Info' and 'log4Debug' macros with NSLog to get this working.
  • 我在这里有一个属性来缓存登录用户,类型符合协议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

回答by Daniel

This means that when you have a token saved (cached) or otherwise already available, the Facebook iOS library still requires you to use the open method to reinitialise a session.

这意味着当您保存(缓存)或以其他方式可用的令牌时,Facebook iOS 库仍要求您使用 open 方法重新初始化会话。

Doing so will if it can reuse an existing token (and this is your case), and in this case the UX (user experience - ie, app switching or Facebook login popup) will not be triggered.

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

The user impression is that he never logged out, but in the app what is happening is you are contacting Facebook to reopen a session.

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

The reason this is designed as such is because in the case the token is available but expired, the Facebook library will tell you - "hey token expired, consider yourself logged out unless you get a new token now."

之所以如此设计,是因为在令牌可用但已过期的情况下,Facebook 库会告诉您 - “嘿,令牌已过期,除非您现在获得新令牌,否则请认为自己已注销。”

Hope that helps.

希望有帮助。

回答by user1592841

Try following code sample:

尝试以下代码示例:

/////////////////////////////////

-(void)CallBackOpenURLFromDelegate:(NSURL *)url
{
    [FBSession.activeSession handleOpenURL:url];
}

-(id)init
{
    self = [super init];
    FBSessionTokenCachingStrategy* pToken = [[[FBSessionTokenCachingStrategy alloc]initWithUserDefaultTokenInformationKeyName:@"STokenInfoX"]autorelease];
    FBSession.activeSession = [[FBSession alloc] initWithAppID:FACEBOOK_AppId
                                                   permissions:[NSArray arrayWithObject:@"status_update"]
                                               urlSchemeSuffix:@""
                                            tokenCacheStrategy: pToken];
    return self;
}


-(void)dealloc
{
    [FBSession.activeSession close];
    [super dealloc];
}

-(void) UploadImpl:(NSString*)strImagePath
{
    FBRequest *photoUploadRequest = [FBRequest requestForUploadPhoto: [UIImage imageWithContentsOfFile:strImagePath ]];
    [photoUploadRequest startWithCompletionHandler:^(FBRequestConnection *connection, id result, NSError *error)
    {
        NSLog(@"%@",[error description]);
        //self.delegate
    }];
}

回答by Javier Figueroa

This may be an old thread, but now a days all you have to do is call handleDidBecomeActive in your FBSession object from within (void)applicationDidBecomeActive:(UIApplication *)application in your app delegate.

这可能是一个旧线程,但现在您所要做的就是从应用程序委托中的 (void)applicationDidBecomeActive:(UIApplication *)application 中调用 FBSession 对象中的 handleDidBecomeActive 。

For example:

例如:

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    [[[MLSocialNetworksManager sharedManager] MLFacebook] handleDidBecomeActive];
}

Where MLFacebook is my FBSession object.

其中 MLFacebook 是我的 FBSession 对象。

回答by Jerry Juang

simply call in your init view controller

只需调用您的 init 视图控制器

self.FBloginView = [[FBLoginView alloc] init];