I have a button to share a link. I'm using basically two calls:
openActiveSessionWithReadPermissions
and requestNewPublishPermissions
.
So this is the button action:
- (IBAction) shareFacebookButtonAction:(id)sender
if (![[FBSession activeSession] isOpen])
{
NSArray *permissions = @[@"read_friendlists", @"email"];
[FBSession openActiveSessionWithReadPermissions:permissions
allowLoginUI:YES
completionHandler:^(FBSession *session,
FBSessionState state,
NSError *error)
{
if (FB_ISSESSIONOPENWITHSTATE([session state]))
{
[self _prepareShare];
}
else
{
// show alert view with error
}
}];
}
else
{
[self _prepareShare];
}
}
and with this I'm asking for publish permission, if no permissione are found in session
-(void) _prepareShare;
{
if ([FBSession.activeSession.permissions
indexOfObject:@"publish_actions"] == NSNotFound)
{
[FBSession.activeSession
requestNewPublishPermissions:
[NSArray arrayWithObject:@"publish_actions"]
defaultAudience:FBSessionDefaultAudienceFriends
completionHandler:^(FBSession *session, NSError *error)
{
if (!error)
{
[self _share];
}
else
{
//error
}
}];
} else
{
[self _share];
}
}
_share just posts something
-(void) _share;
{
NSMutableDictionary *params_dict = [NSMutableDictionary dictionary];
// setting some params
[FBRequestConnection startWithGraphPath:@"me/feed" parameters:params_dict HTTPMethod:@"POST" completionHandler:^(FBRequestConnection *connection, id result, NSError *error)
{
if (result)
{
// sharing succedeed, do something
}
else if (error)
{
//sharing failed, do something else
}
}];
}
First time I try to share (already logged on FB in iOS6 and app already authorized) completion handler of openActiveSessionWithReadPermissions
is being called twice:
once with FBSessionStateOpen and once with FBSessionStateOpenTokenExtended (from the openSessionForPublishPermissions call).
As a consequence, _share
is also called twice, first time in the else
part of _prepareShare
(if I already have publish permissions) and the second time in the completion handler of openSessionForPublishPermissions.
So I have a double post on Facebook wall, just the first time I ever share in the app. I also had a crash report for FBSession: It is not valid to reauthorize while a previous reauthorize call has not yet completed
(I couldn't be able to make it happen again).
What is the proper way to handle this situation?
It appears that by design, Facebook SDK retains references to block handlers, even after they have been called. Thus, in your call to openActiveSessionWithReadPermissions the completion handler may be called numerous times, in case the session state changes. See Facebooks comment on this issue here.
As a work around, you might want to implement your own mechanism that ensures the handler is fired only once:
__block FBSessionStateHandler runOnceHandler = ^(FBSession *session,
FBSessionState status,
NSError *error) { /* YOUR CODE HERE */ };
...
[FBSession openActiveSessionWithReadPermissions:YOUR_PERMISSIONS
allowLoginUI:YES
completionHandler:^(FBSession *session,
FBSessionState status,
NSError *error) {
if (runOnceHandler) {
runOnceHandler(session, status, error);
runOnceHandler = nil;
}
}
];
You Can use this
- (IBAction)facebookBasti:(id)sender {
if(FBSession.activeSession.isOpen){
[[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
if (!error) {
NSLog(@" Email = %@",[user objectForKey:@"email"]);
}
}];
NSLog(@"POST TO WALL -- %@",FBSession.activeSession.accessToken);
[self publishFacebook];
}
else {
// try to open session with existing valid token
NSArray *permissions = [[NSArray alloc] initWithObjects:
@"publish_actions",@"email",
nil];
FBSession *session = [[FBSession alloc] initWithPermissions:permissions];
[FBSession setActiveSession:session];
if([FBSession openActiveSessionWithAllowLoginUI:NO]) {
// post to wall
[[FBRequest requestForMe] startWithCompletionHandler:^(FBRequestConnection *connection, NSDictionary<FBGraphUser> *user, NSError *error) {
if (!error) {
NSLog(@" Email = %@",[user objectForKey:@"email"]);
}
}];
NSLog(@"POST TO WALL -- %@",FBSession.activeSession.accessToken);
[self publishFacebook];
} else {
// you need to log the user
NSLog(@"login");
[FBSession openActiveSessionWithPermissions:permissions
allowLoginUI:YES
completionHandler:^(FBSession *session,
FBSessionState state,
NSError *error) {
NSLog(@"POST TO WALL -- %@",FBSession.activeSession.accessToken);
[self publishFacebook];
}];
}
}
}
and publishFacebook method
-(void)publishFacebook
{
NSMutableDictionary *postParams2= [[NSMutableDictionary alloc] initWithObjectsAndKeys:
haberLink, @"link",
@"abc.com", @"name",
title, @"caption",
desc, @"description",
nil];
[FBRequestConnection
startWithGraphPath:@"me/feed"
parameters:postParams2
HTTPMethod:@"POST"
completionHandler:^(FBRequestConnection *connection,
id result,
NSError *error) {
NSString *alertText;
if (error) {
alertText = [NSString stringWithFormat:
@"error: domain = %@, code = %d",
error.domain, error.code];
} else {
alertText = [NSString stringWithFormat: @"Shared Facebook"];
[[[UIAlertView alloc] initWithTitle:@"Shared Facebook"
message:alertText
delegate:self
cancelButtonTitle:@"Ok"
otherButtonTitles:nil]
show];
}
}];
}
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