Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/105.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在iOS应用程序中处理多个Facebook用户登录_Ios_Facebook_Facebook Sdk 3.0 - Fatal编程技术网

在iOS应用程序中处理多个Facebook用户登录

在iOS应用程序中处理多个Facebook用户登录,ios,facebook,facebook-sdk-3.0,Ios,Facebook,Facebook Sdk 3.0,我有一个可以有多个用户的iOS应用程序,我想将Facebook集成到其中。我想缓存每个用户的登录凭据。用户将有一个应用程序登录,因此每个用户只能使用自己的Facebook creds。Facebook的文档表明,您可以通过覆盖以下FBSessionTokenCachingStrategy对象来管理多个用户的会话令牌: 我使用的是本地缓存方法,我让它在用户登录到我的应用程序时工作,然后如果他们有相关的Facebook令牌,我将他们登录到那里的会话中。否则,我会提示他们使用Facebook的API

我有一个可以有多个用户的iOS应用程序,我想将Facebook集成到其中。我想缓存每个用户的登录凭据。用户将有一个应用程序登录,因此每个用户只能使用自己的Facebook creds。Facebook的文档表明,您可以通过覆盖以下FBSessionTokenCachingStrategy对象来管理多个用户的会话令牌:

我使用的是本地缓存方法,我让它在用户登录到我的应用程序时工作,然后如果他们有相关的Facebook令牌,我将他们登录到那里的会话中。否则,我会提示他们使用Facebook的API输入Facebook凭据,该API会将用户重定向到Facebook web登录页面

[FBSession openActiveSessionWithReadPermissions:@[@"basic_info"]
                                   allowLoginUI:YES
                              completionHandler:
 ^(FBSession *session, FBSessionState state, NSError *error)
 {
     [self loginToFacebookEnd:session state:state error:error];
 }];
上述方法对于第一个用户非常有效。第二个登录的用户按预期重定向到Facebook web登录页面,但第一个用户现在通过safari登录,第二个用户现在使用第一个用户凭据登录

我希望能够让用户不继续登录safari,或者能够使用类似嵌入式web对话框的功能。然而,根据Facebook API文档,嵌入式对话框似乎不允许我在应用程序重新启动后加载用户令牌:

嵌入式WebView登录对话框的缺点:人们必须填写 每次通过登录流时,他们的登录凭据。”

此外,从嵌入式WebView保存令牌时,调用以下方法会清除我的令牌缓存:

FBSession *session = [[FBSession alloc] initWithAppID:nil
                                          permissions:@[@"basic_info"]
                                      urlSchemeSuffix:nil
                                   tokenCacheStrategy:tokenCaching];
有人知道如何支持多个用户从iOS应用程序登录Facebook,而不将第一个用户的凭据缓存在Safari中吗

更新1

好的,我知道现在可以使用嵌入式WebView处理多个用户,因为Facebook SDK附带的一个示例程序(SwitchUserSample)就是这样做的。加载FBSession似乎有点问题,因为很多值都是空的,尽管我调用的代码与示例完全相同。是否有人知道什么会导致会话恢复为这样:

<FBSession: 0x16d9f3a0, state: FBSessionStateCreated, loginHandler: 0x0, appID: 658013034244859, urlSchemeSuffix: , tokenCachingStrategy:<FBSessionTokenCachingStrategy: 0x16d56190>, expirationDate: (null), refreshDate: (null), attemptedRefreshDate: 0001-12-30 00:00:00 +0000, permissions:(null)>
我这样称呼它:

+ (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI
{
    BOOL openSessionResult = NO;    
    FBSession *session = [self createSessionForSlot:1];

    // If showing the login UI, or if a cached token is available, then open the session.
    if (allowLoginUI || session.state == FBSessionStateCreatedTokenLoaded)
    {
        // For debugging purposes log if cached token was found
        if (session.state == FBSessionStateCreatedTokenLoaded)
        {
            NSLog(@"Cached token found.");
        }

        // Set the active session
        [FBSession setActiveSession:session];

        // If the session state is not any of the two "open" states when the button is clicked
        if (FBSession.activeSession.state != FBSessionStateOpen && FBSession.activeSession.state != FBSessionStateOpenTokenExtended)
        {
            // Open the session.
            [session openWithBehavior:FBSessionLoginBehaviorForcingWebView
                    completionHandler:^(FBSession *session,
                                        FBSessionState state,
                                        NSError *error)
             {
                 [SocialInteraction loginToFacebookEnd:session state:state error:error];
             }];
        }

        // Return the result - will be set to open immediately from the session
        // open call if a cached token was previously found.
        openSessionResult = session.isOpen;
    }
    return openSessionResult;
}

令人沮丧的是,如果我将登录行为从FBSessionLoginBehaviorForcingWebView更改为FBSessionLoginBehaviorWithFallbackTowView,那么令牌将正确加载!但是,这种行为对我的应用程序不起作用。我还缺少一些其他设置,可以让嵌入式WebView缓存其令牌。

我将此从“注释”移动到“答案”,以便键入更多内容:

如果您的
FBSession
实例的状态是
FBSessionStateCreated
,那么您就不会有
expirationDate
属性等。根据我的经验,它必须有效地打开(
FBSessionStateCreatedTokenLoaded
FBSessionStateOpen
FBSessionStateOpenTokenExtended
)。FBSession对象是否有关联的accessToken?如果是的话,那么继续尝试打开会话,看看状态是否发生了变化,并且您得到了以前为NULL的值

要在我拥有有效的
accessToken
时打开
FBSession
,我通常使用:

[FBSession openActiveSessionWithAllowLoginUI:NO];
更新1:

好的,这是web视图的一种变通方法-如果您使用Safari,您可以使用下面的代码清除用户的cookie。我可能会在cookie的域中搜索
Facebook.com
fb.com
(可能需要对fb cookie域进行一些测试):


如果FBSession实例的状态为FBSessionStateCreated,那么您就不会有expirationDate属性等。根据我的经验,它必须有效地打开(FBSessionStateCreatedTokenLoaded、FBSessionStateOpen或令牌扩展的一个-现在忘记它的名称)。FBSession对象是否有关联的accessToken?如果是,则继续并尝试打开会话,查看状态是否发生变化,并在以前为空的位置获取值。该状态似乎停留在FBSessionStateCreated状态,即使在我尝试打开会话之后。当您查询FBSession实例的访问令牌时-您能够获取有效的访问令牌吗?当我反序列化令牌时,它仅在由FBSessionLoginBehaviorForcingWebView以外的行为设置时才有效。我已经更新了上面的评论,以包括使用不同行为进行反序列化的令牌的外观。我已经在我的答案中添加了一个解决方法-让我知道这是否有效。如果您需要使用web视图解决方案,我认为如果您能够共享它,直接调试您的项目会更容易?请随意删除FB应用程序ID(可以使用我自己的)。嗯。。。这是一个有趣的想法!我会查一查。
+ (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI
{
    BOOL openSessionResult = NO;    
    FBSession *session = [self createSessionForSlot:1];

    // If showing the login UI, or if a cached token is available, then open the session.
    if (allowLoginUI || session.state == FBSessionStateCreatedTokenLoaded)
    {
        // For debugging purposes log if cached token was found
        if (session.state == FBSessionStateCreatedTokenLoaded)
        {
            NSLog(@"Cached token found.");
        }

        // Set the active session
        [FBSession setActiveSession:session];

        // If the session state is not any of the two "open" states when the button is clicked
        if (FBSession.activeSession.state != FBSessionStateOpen && FBSession.activeSession.state != FBSessionStateOpenTokenExtended)
        {
            // Open the session.
            [session openWithBehavior:FBSessionLoginBehaviorForcingWebView
                    completionHandler:^(FBSession *session,
                                        FBSessionState state,
                                        NSError *error)
             {
                 [SocialInteraction loginToFacebookEnd:session state:state error:error];
             }];
        }

        // Return the result - will be set to open immediately from the session
        // open call if a cached token was previously found.
        openSessionResult = session.isOpen;
    }
    return openSessionResult;
}
[FBSession openActiveSessionWithAllowLoginUI:NO];
NSHTTPCookie *cookie;
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (cookie in [storage cookies]) {
    [storage deleteCookie:cookie];
}
[[NSUserDefaults standardUserDefaults] synchronize];