2013-05-22 8 views
8

Ich habe eine Schaltfläche, um einen Link zu teilen. Ich verwende grundsätzlich zwei Anrufe: openActiveSessionWithReadPermissions und requestNewPublishPermissions.Facebook iOS SDK 3.5.1: openActiveSessionWithReadPermissions - Abschluss-Handler zweimal aufgerufen

Das ist also die Button-Aktion:

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

und damit ich um Erlaubnis zu veröffentlichen, wenn keine permissione in Sitzung

-(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 nur Beiträge etwas

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

Das erste Mal versuche ich zu teilen (bereits angemeldet FB in iOS6 und App bereits autorisiert) Der Beendigungshandler openActiveSessionWithReadPermissions wird zweimal aufgerufen: einmal mit FBSessionStateOpen und einmal mit FBSessionStateOpenTokenExtended (aus dem Aufruf openSessionForPublishPermissions). Als Folge wird _share auch zweimal aufgerufen, zum ersten Mal im else Teil von _prepareShare (wenn ich bereits veröffentlichen Berechtigungen habe) und das zweite Mal im Abschluss-Handler von openSessionForPublishPermissions. Also ich habe einen doppelten Post auf Facebook Wall, nur das erste Mal, dass ich jemals in der App teile. Ich hatte auch einen Absturzbericht für FBSession: It is not valid to reauthorize while a previous reauthorize call has not yet completed (ich konnte es nicht wieder passieren lassen).

Was ist der richtige Weg, um mit dieser Situation umzugehen?

+0

Bitte beachten Sie die Antwort in diesem Beitrag: [1] [1] [link Beschreibung hier eingeben]: http://stackoverflow.com/questions/12915420/facebook-ios-3-1- sdk-login-mit-Publish-Erlaubnis-Rückrufe – Chengjiong

Antwort

2

Können Sie verwenden diese

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

            }]; 
    } 
} 

}

und publishFacebook Methode

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

    } 
}]; 

}

+0

dank für Ihre Hilfe, aber ich mag wirklich verstehen, wenn ich etwas tue falsch und dem richtigen Weg, um dieses Verhalten Facebook – laucel

+0

in Ihrer Vorbereitung Anteil Methode behandeln Sie haben bereits Post es, wenn man es so nennen _share Methode Post wieder –

+0

ja, aber man ist in, wenn Block (wenn ich nicht die Erlaubnis veröffentlichen müssen, danach fragen, dann Aktie), der andere ist in der else-Block (wenn ich bereits zu veröffentlichen haben Erlaubnis, teilen Sie einfach). Das Problem ist, dass _share in der else-Anweisung von _prepareshare von FBSessionStateOpenTokenExtended ausgelöst genannt wird, während requestNewPublishPermissions noch nicht seinen Abschluss Handler aufgerufen hat, wenn _share erneut aufgerufen wird – laucel

13

Es scheint, dass durch Design, Facebook SDK Referenzen behält Handler zu blockieren, auch nachdem sie angerufen wurden. Daher kann der Completion-Handler in Ihrem Aufruf an openActiveSessionWithReadPermissions zahlreiche Male aufgerufen werden, falls sich der Sitzungszustand ändert. Siehe Facebooks comment on this issue here.

Als eine Arbeit um, könnten Sie Ihren eigenen Mechanismus implementieren möchten, dass die Handler nur einmal abgefeuert wird sichergestellt:

__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; 
             } 

            } 
    ]; 
1

Bitte Upgrading from 3.0 to 3.1 lesen, der Absatz insbesondere für Read & Schreibberechtigungen Vorstellung Getrennt . Es scheint, als ob Facebook SDK nicht dazu gedacht ist, auf diese Weise verwendet zu werden.

Sie müssen nun die Lese- und Veröffentlichungsberechtigung separat anfordern (und in dieser Reihenfolge). Wahrscheinlich werden Sie die Leseberechtigungen für die Personalisierung anfordern, wenn die App gestartet wird und der Benutzer sich zuerst anmeldet. Später kann Ihre App ggf. Veröffentlichungsberechtigungen anfordern, wenn sie Daten an Facebook senden möchte.

und

Es ist wichtig, dass Sie nicht einfach versuchen, die beiden einzelnen Methoden back-to-back rufen Sie eine der veralteten Funktionen zu ersetzen.

Ich frage mich, wie Sie dieses Problem gelöst haben. BTW, ich bekomme den gleichen Absturzbericht (FBSession: Es ist nicht zulässig, erneut zu autorisieren, während ein vorheriger Neuautorisierungsanruf noch nicht abgeschlossen ist).

Verwandte Themen