Search code examples
iosfacebooksessionios5facebook-ios-sdk

Facebook iOS SDK , exception against FBSession, *** Assertion failure in -[FBSession close]


I'm using facebook sdk 3.0.8 for ios. when i try to login with facebook it works fine but sometimes when i try to login after logging out then app is being crashed.

here is exception message

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

can you please tell me where i'm going wrong?

Here is code inside 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
    }
}

Code Inside View Controller

-(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"];
      } 
}

Edit:

removed the following code and now it works fine

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

here is updated code

 -(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
             ];
        } 
    }

Solution

  • Looking at FBSession.m, the assertion in close is as follows:

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

    Are you calling -close from a thread other than the one you created the session on?

    Looking into this further. You're misusing the API. You are creating

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

    but then you are calling

    [FBSession openActiveSessionWithPermissions ...
    

    which creates an entirely new session. Meaning you never opened appDelegate.session, and therefore you should not try to close it. What you should be doing instead is the following:

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

    Another option is to just do:

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