iPhone Facebook Connect logout crash after changing views - iphone

I've implemented Facebook Connect in my app just like the sample app that Facebook provides and it works well. After a user chooses to share data via Facebook they are taken to a new view and presented with the FB login dialog. When the user is done they exit the FB sharing view and return to my app's previous view. The user stays logged in as long as they don't logout - even if they exit the FB sharing view. This is good and as expected.
I'm using the same viewDidLoad method as the sample SessionViewController.m, and this is where _session is initialized:
- (void)viewDidLoad {
[_session resume];
_loginButton.style = FBLoginButtonStyleWide;
}
However I noticed that if the user presses the Logout button after exiting and re-loading the FB sharing view it will throw SIGABRT or EXC_BAD_ACCESS and crash the app. The EXC_BAD_ACCESS error occurs at the [dialog show] line of the Login button's touchUpInside method:
- (void)touchUpInside {
if (_session.isConnected) {
[_session logout];
} else {
FBLoginDialog* dialog = [[[FBLoginDialog alloc] initWithSession:_session] autorelease];
[dialog show];
}
Even though the user is connected the touchUpInside method is seeing a disconnected session... Sometimes instead of crashing after pressing the Logout button the logout will be successful but the view's status text remains "Logged in as ..." and the set status/upload image buttons are not hidden. Trying to log in again throws a SIGABRT, which looks due to a nil _session.sessionKey in FBRequest.m:344:
[_params setObject:_session.sessionKey forKey:#"session_key"];
Is there something I should be retaining or doing differently across view changes?
EDIT: I found another user having this same issue on the Facebook Developer Forums:
http://forum.developers.facebook.com/viewtopic.php?pid=193727#p193727
There is no solution posted but if I find one I'll update this question.

_session is nil at that point, right (that's consistent with the "always showing not connected"). Where do you initialize _session?
ETA: This is your code, which is taking the place of SessionViewController provided by Facebook Connect, right?
I can't figure out how _session could have been released, but that's what it seems like.
Adding:
You might want to change your button handler to
[_session resume];
and then do whatever you need to do in the didLogin delegate handler. That way the _session instantiates the FBLoginDialog for you.

Related

iPhone Gigya integration sharing Facebook, twitter inconsistency

I am currently integrating facebook and twitter for iphone with gigya.
For Twitter sometimes its sharing and sometimes don't. Facebook also happening same as well.
lately facebook not even opening its login in screen. On device unlike simulator delegate methods like LoginDidFail, DidLogin called more than once.not sure why.
I am not storing any object to store provider info when login happens.
Can you please let me know why this inconsis
This seems like a multi part question.I would need more information to get a clearer understanding. Please provide code snippets if possible. Meanwhile, please see see my responses below:
Inconsistent Sharing
This might be something to do with how your userAction is being defined.
(http://wiki.gigya.com/030_API_reference/010_Client_API/010_Objects/UserAction_object)
Login Screen not loading
Typically this is down to social Network Applications not set up correctly.
(http://wiki.gigya.com/035_Socialize_Setup/005_Opening_External_Applications)
Event Delegate methods called repeatedly
This may be down do multiple instances of the GSAPI class.
Hope that helps.
I am using following code snippet
GSAPI *gsAPI // declared this in header file
gsAPI = [[GSAPI alloc] initWithAPIKey:XX viewController:self]; // i kept this in viewDidload
// add this code to have facebook and twitter on provider list. this was put in in one method which will be called when user tries to share
GSDictionary *pParams5 = [[GSDictionary new] autorelease]; [pParams5 putStringValue:#"facebook,twitter" forKey:#"enabledProviders"];
[gsAPI showAddConnectionsUI:pParams5 delegate:self context:nil];
//this method called when login fails -(void)gsLoginUIDidFail:(int)errorCode errorMessage:(NSString*)errorMessage context:(id)context {
}
// this method called on successful login
- (void) gsLoginUIDidLogin:(NSString*)provider user:(GSDictionary*)user context:(id)context {
GSDictionary *userAction = [[GSDictionary new] autorelease];
[userAction putStringValue:#"title" forKey:#"title"];
[userAction putStringValue:#"userMessage" forKey:#"userMessage"];
[userAction putStringValue:#"desc" forKey:#"description"];
[userAction putStringValue:#"imageurl" forKey:#"linkBack"];
GSDictionary *pParams5 = [[GSDictionary new] autorelease];
[pParams5 putGSDictionaryValue:userAction forKey:#"userAction"];
[gsAPI sendRequest:#"socialize.publishUserAction" params:pParams5 delegate:self context:nil];
}
-(void) gsDidReceiveResponse:(NSString*)method response:(GSResponse*)response context:(id)context {
//showing alert messages on successful sharing
//this method getting called more than twice on device
}

fbconnect logout memory leak

this is the first time I post a question here. Usually, I found help on web for my Iphone projects problems, but here I am REALLY STUCK !
I use the facebook iphone-sdk to post some infos on a user's wall. Everything works fine. But I have a leak memory when I logout with the fbconnect loginbutton.
Here is the code I used in the implementation file for a test :
- (void)viewDidLoad {
//session facebook
session = [[FBSession sessionForApplication:#"APP_KEY"
secret:#"SECRET_KEY"
delegate:self] retain];
//facebook bouton connect
FBLoginButton *logButton = [[[FBLoginButton alloc] init] autorelease];
[self.view addSubview:logButton];
[super viewDidLoad];
}
- (void) session:(FBSession *) session didLogin:(FBUID) uid {
NSLog(#"login ok");
}
- (void)sessionDidLogout:(FBSession*) session {
NSLog(#"didLogOut called");
}
as you see I did nothing. So when I test this app, I push the connect to facebook buton and I log in without problems.
But when I push the same button, which is labeled now logout, I log out and then just after that a memory leak appears.
In instruments I can find the origin of the problem and it seams that it is the logout method in FBSession.m file who cause this leak. And especially when the unsave method is called from logout method because if I comment the call, the memory leaks does not appear.
So I need help to figure out what causes this.
I am a newbie myself but does putting [super viewDidLoad] on top instead of the bottom help? We are adding your session information to the view and we expect it to be added after all the parent class views are loaded.

Face book connect is not working

I have integrated Facebook connect in my iphone application.
when user clicks on a button i am calling a method which has the following code.
session1 = [[FBSession sessionForApplication:kApiKey secret:kApiSecret delegate:self] retain];
dialog = [[[FBLoginDialog alloc] initWithSession:session1] autorelease];
[dialog show];
when the user login into the Facebook with his username and password, if the user name and password are incorrect it is showing the message correctly.
but when the user enters correct user name and password, the entire face book window is closing without giving any message.
Vodkhang has the right answer, but also know that since Facebook connect stores info in the user defaults, you should insert a
if (![session1 resume]) {
before you invoke the dialog. This will ensure that future uses of the app will not generate the same login dialog.
The didLogin: delegate function will still be invoked when the session is resumed, so you can still do whatever you need with the FBUID. One simple thing you can do is create a hidden Label in Interface Builder and assign the FBUID to that label in the didLogin function. That way you can always pull that label's text if you need the FBUID later.
It works correctly. The facebook window closes mean your user login successfully. You should handle some delegate:
#pragma mark FBSessionDelegate
- (void)session:(FBSession*)session didLogin:(FBUID)uid {
}
- (void)sessionDidNotLogin:(FBSession*)session {
}
- (void)session:(FBSession*)session willLogout:(FBUID)uid {
}
- (void)sessionDidLogout:(FBSession*)session {
// NCLog(#"FacebookHelper logged out");
}
Then you will know what happens to the login process

FBConnect for iPhone: sessionDidNotLogin, sessionDidLogout, session didLogin not called the second time I load a view

My problem is very similar to this question, however I am posting a new one, as the answer to the aforementioned does not seem to solve my problem.
I have a multiview application - the first view is where the user logs in to Facebook, and the second where he picks an image and uploads it there. The first time the app runs, everything works fine, however if I return to the login view and press logout, then any calls to sessionDidNotLogin, sessionDidLogout or session didLogin don't seem to work.
I found out that the first time, if I NSLog(#"%#",session.delegates); I have 2; my LoginViewController and the FBLoginButton. However, apart from that first time, the same log prints only the LoginViewController and not the FBLoginButton. I guess this is connected somehow, but I don't know how to solve it.
Do I have to manually add the FBLoginButton to the session delegates, or I'm doing something else wrong here?
Thank you for any help/suggestion.
I figured out the problem, thanks to a post from the Facebook developers forum.
Everytime a view was loaded, I was creating a new session instance (even though I thought that it would be a singleton and the library should have taken care of it).
So, in order to make this work:
fbSession = [FBSession session];
if (!fbSession) {
fbSession = [[FBSession sessionForApplication:kApiKey secret:kApiSecret delegate:self] retain];
} else {
[[fbSession delegates] addObject:self];
}

Facebook Connect for iPhone - want to log in and post in one step

This is a repost from the Facebook developer forums, where no-one has responded yet.
This is what I would like to do:
user touches Connect button
code retrieves session and attempts to resume
if session does not resume, pop up login dialog
pop up feed dialog (after user has successfully logged in)
What actually happens in the case where a login is needed:
user touches Connect button
login dialog comes up (but user never sees it)
feed dialog immediately comes up on top of it
feed dialog spins forever because it is unable to connect
There doesn't seem to be a way to use the delegate methods to tell if the user has finished logging in; dialogDidSucceed never seems to be called for the login dialog. For that matter, there doesn't seem to be a way to tell if they cancelled out either (in which case going on to the feed dialog would be pointless).
Am I attempting the impossible?
- (void) login {
session = [FBSession sessionForApplication:... secret:... delegate:self];
FBLoginDialog *dialog = [[[FBLoginDialog alloc] initWithSession:session] autorelease];
dialog.delegate = self;
[dialog show];
}
- (void) session:(FBSession *)newSession didLogin:(FBUID)newUid {
session = newSession;
uid = newUid;
FBFeedDialog* dialog = [[[FBFeedDialog alloc] init] autorelease];
dialog.delegate = self;
dialog.templateBundleId = ...
dialog.templateData = ...
[dialog show];
}
While Ed's answer is correct, he's not explaining why.
When you send the show message the first dialog, it shows, but doesn't wait for it to close.. the program execution moves along to the next line. Therefore you are asking the next dialog to show, which it does – right on top of the previous one. This is true for dialogs or alert views on the iPhone platform.
Ed's answer is showing the first dialog but not continuing. What is not obvious, is that when the user successfully logs in, the session delegate is sent the -didLogin: message. You may have expected a dialog delegate message?
Be careful though, as other situations that you code may result in the session login, and it will run the code in the delegate method.. and you may not want that!
An example of this is when the session resumes. To keep it straight-forward, assume you have two actions in your app, and both publish a short story to the user feed. When you ask the user to login – or resume – their existing session, the session delegate message -didLogin: will be sent. You need to make sure your implementation of -didLogin: handles both situations, and both actions.
As an aside, consider using the latest SDK and the stream.publish request, or the FBStreamDialog class (instead of FBFeedDialog)for pushing the story to facebook.
(I'm "answering my own question" because this was too long to leave as a comment on the previous entry)
I don't think I explained the problem clearly enough... let me try again. The code below is executed when the user touches the "share on facebook" button:
// get session
if (session == nil) {
session = [FBSession sessionForApplication.....];
}
// log in if necessary
if (![session resume]) {
FBLoginDialog* dialog = [FBLoginDialog alloc...];
[dialog show];
}
// post feed story
FBFeedDialog* dialog = [FBFeedDialog alloc...];
dialog.delegate = self;
dialog.templateBundleID = ...;
[dialog show];
This does not work, for obvious reasons - both dialogs come up right away. While I see that splitting it into two methods would help, the main problem is that I have nothing on which to trigger bringing up the feed dialog. dialogDidSucceed doesn't seem to get called for the login dialog, and there doesn't seem to be anything else I can look for. Most apps split this into two buttons, meaning the user has to touch a second button in order to initiate posting a feed story. I was hoping to avoid that, but I can't find a way to do it.