views:

751

answers:

2

I am trying to use the FBConnect SDK to connect to Facebook. Everything works fine the first time the user tries to login: the delegate method session:didLogin gets called, then I am able to acquire the extended permission to update the user's status and to upload a picture. However, when the user taps the logout button, trying to connect again, starting from the second time on this always results in session:didLogin NEVER called. This occurs both when the session is cached (the user clicks on the checkbox in the FBLoginDialog) and when it is not.

I just need to recognize correctly when the session is established in order to begin showing the button that the user needs to tap in order to acquire the extended permission.

What is the correct/expected behavior among the following possibilities?

1) if the session is cached then the second time the user logs in session:didLogin will not be called but the session is actually connected (i.e. _session.IsConnected must be YES) and nothing else needs to be done to establish the session;

2) if the session is cached then the second time the user logs in session:didLogin will not be called and the session is not connected, so that further action is required to establish the session (what should I do in this case?);

3) if the session is not cached, then the second time the user logs in session:didLogin will be called and the session is established;

The relevant code follows. Please let me know if something is wrong and your current best practice to achieve multiple correct logins independently of the status of the session (cached or not). Thank you in advance.

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:@"FacebookViewController" bundle:nibBundleOrNil]) {

        if (kGetSessionProxy) {
            _session = [[FBSession sessionForApplication:kApiKey getSessionProxy:kGetSessionProxy delegate:self] retain];

        } else {
            _session = [[FBSession sessionForApplication:kApiKey secret:kApiSecret delegate:self] retain];
        }
    }

    return self;
}


- (void)viewDidAppear:(BOOL)animated {

    [super viewDidAppear:animated];

    BOOL resumed = [_session resume];

    _loginButton.style = FBLoginButtonStyleWide;


     if (_session.isConnected) {
         _permissionButton.hidden = NO;
     }
     else{
         _permissionButton.hidden = YES;
     }

    _statusButton.hidden = YES;
    _photoButton.hidden = YES;


    if(([_session isConnected] || resumed) && self.name){
        _label.text = [NSString stringWithFormat:@"%@ %@", NSLocalizedString(@"Logged in as", nil), self.name];     
    }
    else{
        _label.text = [NSString stringWithFormat:@"%@", NSLocalizedString(@"You are not logged in", nil)];  
    }



}



- (void)session:(FBSession*)session didLogin:(FBUID)uid {

    NSLog(@"session:didLogin:");

    if(_session && session != _session){
        [_session release], _session = nil;
    }

    if(!_session){
        _session = [session retain];
    }

    _label.text = @"";
    _permissionButton.hidden = YES;
    _statusButton.hidden     = YES;
    _photoButton.hidden      = YES;

    NSString* fql = [NSString stringWithFormat:@"select uid,name from user where uid == %lld", session.uid];


    NSDictionary* params = [NSDictionary dictionaryWithObject:fql forKey:@"query"];
    [[FBRequest requestWithDelegate:self] call:@"facebook.fql.query" params:params];



}


- (void)dealloc {

    [_session.delegates removeObject: self];
    [_session release], _session = nil;
    [_permissionButton release], _permissionButton = nil;
    [_statusButton release], _statusButton = nil;
    [_photoButton release], _photoButton = nil;
    [name release], name = nil;

        [super dealloc];
}
A: 

Hi unforgiven,

Could you post your logout method?

Are you doing

[_session logout];
vfn
No, I am not doing [_session logout] anywhere in the code. Logout happens when the user taps the logout button which is the same facebook login button that turns into the logout button after the user logs in. I tried in some of my experiments putting [_session logout] in the dealloc() method just before calling [_session.delegates removeObject: self]; [_session release], _session = nil; but it did't help. Basically the logout code is the one from the FBConnect sdk.
unforgiven
I'm having this exact same problem and cannot figure it out. From my testing, if the Facebook view is presented from another view (are you doing this?) things start to go very wrong the second, third, fourth time you present the Facebook view. Facebook Connect seems buggy to me.
Ian
A: 

Now it works. Here is the relevant code handling the session. I am not showing other methods because the session instance is not modified in any way elsewhere. I hope this may be useful to other people.

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:@"FacebookViewController" bundle:nibBundleOrNil]) {

        if (kGetSessionProxy) {
            _session = [[FBSession sessionForApplication:kApiKey getSessionProxy:kGetSessionProxy delegate:self] retain];

        } else {
            _session = [[FBSession sessionForApplication:kApiKey secret:kApiSecret delegate:self] retain];
        }
    }

    return self;
}


- (void)viewDidLoad {

   [_session resume];

   ...

}



- (void)dealloc {
    [_session.delegates removeObject: self];
    [_session release], _session = nil;

        ...

    [super dealloc];
}
unforgiven
Hmm were there no other code changes from your question? I have the same code as your answer but still session: didLogin: doesn't fire after returning to my Facebook sharing view. Are you using @property/@synthesize with _session? Anything else you may have changed?
Ian
There are no other code changes; _session is NOT a property, so no @property/@synthesize appears in the code. I did not change anything else because acquiring permission, updating the status and uploading a picture were already working fine.
unforgiven
Do you present your Facebook view from another view? Or is this the only view that you're working with? I present my Facebook view from another view and wonder if there's something else I need to be doing to get session: didLogin: to fire after returning to the FB view.
Ian
Yes, I show the Facebook view controller starting from another one. Besides the steps I have outlined in my answer, I am not doing anything else.
unforgiven