【问题标题】:Facebook iOS SDK , exception against FBSession, *** Assertion failure in -[FBSession close]Facebook iOS SDK,FBSession 异常,*** 断言失败 -[FBSession close]
【发布时间】:2012-10-25 01:38:25
【问题描述】:

我正在为 ios 使用 facebook sdk 3.0.8。当我尝试使用 facebook 登录时,它工作正常,但有时当我在注销后尝试登录时,应用程序崩溃了。

这里是异常信息

*** Assertion failure in -[FBSession close], /Users/jacl/src/ship/ios-sdk/src/FBSession.m:342

你能告诉我哪里出错了吗?

这是 AppDelegate 中的代码

    - (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation {
    // attempt to extract a token from the url
    return [FBSession.activeSession handleOpenURL:url]; 
}


- (void)applicationWillTerminate:(UIApplication *)application {

    [self.session close];
}

#pragma mark Template generated code


// FBSample logic
// It is possible for the user to switch back to your application, from the native Facebook application, 
// when the user is part-way through a login; You can check for the FBSessionStateCreatedOpenening
// state in applicationDidBecomeActive, to identify this situation and close the session; a more sophisticated
// application may choose to notify the user that they switched away from the Facebook application without
// completely logging in
- (void)applicationDidBecomeActive:(UIApplication *)application {
    /*
     Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
     */


    // FBSample logic
    // this means the user switched back to this app without completing a login in Safari/Facebook App
    if (self.session.state == FBSessionStateCreatedOpening) {
        // BUG: for the iOS 6 preview we comment this line out to compensate for a race-condition in our
        // state transition handling for integrated Facebook Login; production code should close a
        // session in the opening state on transition back to the application; this line will again be
        // active in the next production rev
        //[self.session close]; // so we close our session and start over
    }
}

视图控制器内的代码

-(IBAction)connectWithFacebook{
         DemoAppDelegate *appDelegate = (TotallyCuteAppDelegate *) [[UIApplication sharedApplication]delegate];
        if (!appDelegate.session.isOpen && (appDelegate.session.state != FBSessionStateCreated))
        {
            appDelegate.session = [[FBSession alloc] init];
        }

        NSArray *permissions = [[NSArray alloc] initWithObjects:
                                @"publish_actions",
                                @"email",
                                nil];
        //app crashes here
        [FBSession openActiveSessionWithPermissions:permissions allowLoginUI:YES 
                                  completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
                                      if (session.isOpen) 
                                      {
                                        NSLog(@"LoginVC->Session is open");
                                        appDelegate.session=session; 
                                        [userDefaults setObject:appDelegate.session.accessToken forKey:@"facebook_token"];
                                        [userDefaults setObject:paramFBId forKey:@"facebook_id"];


                                      }
                                      else
                                      {
                                          NSLog(@"LoginVC->Session is not open");
                                      }
                                  }//end completionHandler
         ];

}




-(IBAction)logout:(id)sender{
    DemoAppDelegate *appDelegate = (TotallyCuteAppDelegate *) [[UIApplication sharedApplication]delegate]; 

    if (appDelegate.session.isOpen) {
        [appDelegate.session closeAndClearTokenInformation];

        [[NSUserDefaults userDefaults] removeObjectForKey:@"facebook_id"];
        [[NSUserDefaults userDefaults] removeObjectForKey:@"facebook_token"];
      } 
}

编辑:

删除了以下代码,现在可以正常工作了

  if (!appDelegate.session.isOpen && (appDelegate.session.state != FBSessionStateCreated))
            {
                appDelegate.session = [[FBSession alloc] init];
            }

这里是更新的代码

 -(IBAction)connectWithFacebook{
        if ([InternetChecker isConnected]) 
        {
            DemoAppDelegate *appDelegate = (TotallyCuteAppDelegate *) [[UIApplication sharedApplication]delegate];

    /* Removed following if block
           if (!appDelegate.session.isOpen && (appDelegate.session.state != FBSessionStateCreated))
            {
                appDelegate.session = [[FBSession alloc] init];
            }
    */
            NSArray *permissions = [[NSArray alloc] initWithObjects:
                                    @"publish_actions",
                                    @"email",
                                    nil];

            [FBSession openActiveSessionWithPermissions:permissions allowLoginUI:YES 
                                      completionHandler:^(FBSession *session, FBSessionState status, NSError *error) {
                                          if (session.isOpen) 
                                          {
                                            NSLog(@"LoginVC->Session is open");
                                            appDelegate.session=session; 
                                            [userDefaults setObject:appDelegate.session.accessToken forKey:@"facebook_token"];
                                            [userDefaults setObject:paramFBId forKey:@"facebook_id"];


                                          }
                                          else
                                          {
                                              NSLog(@"LoginVC->Session is not open);
                                          }
                                      }//end completionHandler
             ];
        } 
    }

【问题讨论】:

  • 你误用了API,请看我的回答以获得解释

标签: ios facebook session ios5 facebook-ios-sdk


【解决方案1】:

你应该在主线程上执行你的代码

dispatch_async(dispatch_get_main_queue(), ^{
    [FBSession openActiveSessionWithPermissions:permissions
                                   allowLoginUI:YES
                              completionHandler:^(FBSession *session,
                                                  FBSessionState status,
                                                  NSError *error) {
                                                       // do something
                                                  }];
});

【讨论】:

    【解决方案2】:

    查看FBSession.m,close中的断言如下:

    NSAssert(self.affinitizedThread == [NSThread currentThread], @"FBSession: should only be used from a single thread");
    

    您是从不是您创建会话的线程中调用-close 的吗?

    进一步调查。您在滥用 API。你正在创造

    appDelegate.session = [[FBSession alloc] init]; 
    

    但是你在打电话

    [FBSession openActiveSessionWithPermissions ...
    

    创建一个全新的会话。这意味着您从未打开过appDelegate.session,因此您不应该尝试关闭它。你应该做的是:

    [FBSession openActiveSessionWithPermissions ...
    appDelegate.session = [FBSession activeSession];
    

    另一种选择就是这样做:

    appDelegate.session = [[FBSession alloc] init];
    [appDelegate.session openWithCompletionHandler: ...
    

    【讨论】:

    • 谢谢 yfrancis,我正在尝试您的建议,我想我正在解决我的问题 :)
    • 我应该不使用 appDelegate.session = [[FBSession alloc] init];在整个应用程序中?我只是在关注一些 facebook 示例登录演示,它是 FBSession alloc 在那里
    • 如果您使用openActiveSessionWithPermissions 则不会:FBSession *session = [[[FBSession alloc] initWithPermissions:permissions] autorelease]; 创建一个全新的会话。我已经用更正确的解决方案更新了我的答案
    • 非常感谢 yfrancis。我已经更新了代码现在工作正常。在completionHandler 中初始化appDelegate.session。 appDelegate.session=session;
    • 我正在使用新的 FacebookSdk,它没有 FBSession.m 文件
    猜你喜欢
    • 1970-01-01
    • 2012-08-06
    • 2015-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多