I implemented the whole iOS Facebook login process in one of my iOS Game. In the app, you can either log-in with an email account or through Facebook. I occasionally present a view inviting the user to sync his account with Facebook if he logged-in with an email.
Here is the code I'm using to determine wheither or not I should display this view to the user :
if (FBSession.activeSession.isOpen) {
// Present the view
} else {
// Go somewhere else
}
At first it seemed to work great but it turns out that FBSession.activeSession.isOpen returns NO at some point even though the user is logged in with FB.
My first guess would be that the accessToken expires. I am not sure if it's a good clue because I am doing the following in my application:didFinishLaunchingWithOptions: method (like Facebook recommends to):
if (FBSession.activeSession.state == FBSessionStateCreatedTokenLoaded) {
// Yes, so just open the session (this won't display any UX).
[self openSessionWithCompletionBlock:^{}];
}
So now I have no idea how to reproduce or to fix this problem, any idea? Is it possible that the token expires after the app started? Like if the user keeps the app in background for a quiet long time?
It's just a facebook behavior, you need to 'reopen' the session everytime you launch the app, your guess is sort of right, It's because of the token state, a simple solution is that you check the [FBSession activeSession].isOpen state and if it returns NO call the openActiveSessionWithAllowLoginUI << Yes the same facebook method, but checking all the states it returns.
If the session was previously opened then it uses the stored token to reopen the session, you shouldn't worry about the login UI because it won't show up again as the session was previously opened.
if (![FBSession activeSession].isOpen) {
[self connectWithFacebook];
}
- (void) connectWithFacebook {
// The user has initiated a login, so call the openSession method
// and show the login UI if necessary << Only if user has never
// logged in or ir requesting new permissions.
PPAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate openSessionWithAllowLoginUI:YES];
}
And in the app delegate
- (BOOL)openSessionWithAllowLoginUI:(BOOL)allowLoginUI
{
NSArray *permissions = @[@"any_READ_permision_you_may_need"];
return [FBSession openActiveSessionWithReadPermissions:permissions
allowLoginUI:allowLoginUI
completionHandler:^(FBSession *session, FBSessionState state, NSError *error) {
if (error) {
NSLog (@"Handle error %@", error.localizedDescription);
} else {
[self checkSessionState:state];
}
}];
}
- (void) checkSessionState:(FBState)state {
switch (state) {
case FBSessionStateOpen:
break;
case FBSessionStateCreated:
break;
case FBSessionStateCreatedOpening:
break;
case FBSessionStateCreatedTokenLoaded:
break;
case FBSessionStateOpenTokenExtended:
// I think this is the state that is calling
break;
case FBSessionStateClosed:
break;
case FBSessionStateClosedLoginFailed:
break;
default:
break;
}
}
It's a quick fix and it works, you can reproduce it also just by closing the session but without clearing the token cache using [[FBSession activeSession] close]
You can even change the token cache policy as described here http://developers.facebook.com/docs/howtos/token-caching-ios-sdk/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With