2013-05-22 8 views
8

Ho un pulsante per condividere un collegamento. Sto usando fondamentalmente due chiamate: openActiveSessionWithReadPermissions e requestNewPublishPermissions.Facebook iOS SDK 3.5.1: openActiveSessionWithReadPermissions - gestore di completamento chiamato due volte

Quindi questo è l'azione tasto:

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

e con questo sto chiedendo il permesso pubblicare, se non permissione si trovano in sessione

-(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 solo i messaggi qualcosa

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

Prima volta provo a condividere (FB già connesso in iOS6 e app già autorizzata) il gestore di completamento di openActiveSessionWithReadPermissions viene chiamato due volte: una volta con FBSessionStateOpen e una volta con FBSessionStateOpenTokenExtended (dalla chiamata openSessionForPublishPermissions). Di conseguenza, _share viene anche chiamato due volte, la prima volta nella parte else di _prepareShare (se ho già autorizzazioni di pubblicazione) e la seconda volta nel gestore di completamento di openSessionForPublishPermissions. Quindi ho un doppio post sulla bacheca di Facebook, solo la prima volta che condivido l'app. Ho anche avuto un rapporto di incidente per FBSession: It is not valid to reauthorize while a previous reauthorize call has not yet completed (non potrei essere in grado di farlo accadere di nuovo).

Qual è il modo corretto di gestire questa situazione?

+0

Si prega di vedere la risposta in questo post: [entra Descrizione collegamento qui] [1] [1]: http://stackoverflow.com/questions/12915420/facebook-ios-3-1- sdk-login-with-publish-permission-callbacks – Chengjiong

risposta

2

È possibile utilizzare questo

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

            }]; 
    } 
} 

}

e publishFacebook metodo

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

grazie per il vostro aiuto, ma vorrei davvero capire se sto facendo qualcosa di sbagliato e il modo corretto per gestire questo comportamento di Facebook – laucel

+0

nel metodo di condivisione preparate che avete già post quando chiamate il metodo _share postatelo di nuovo –

+0

sì, ma uno è in se block (se non ho il permesso di pubblicazione, chiedilo, poi condivido), l'altro è nel blocco else (se ho già pubblicato permesso, basta condividere). Il problema è che _share viene chiamato nell'istruzione else di _prepareshare attivata da FBSessionStateOpenTokenExtended, mentre requestNewPublishPermissions non ha ancora chiamato il suo gestore di completamento, quando _share viene chiamato di nuovo – laucel

13

Sembra che in base alla progettazione, Facebook SDK mantiene i riferimenti per bloccare i gestori, anche dopo che sono stati chiamati. Pertanto, nella chiamata a openActiveSessionWithReadPermissions, il gestore di completamento può essere chiamato più volte, nel caso in cui lo stato della sessione cambi. Vedi Facebooks comment on this issue here.

Come un lavoro in giro, si potrebbe desiderare di implementare il proprio meccanismo che assicura il gestore è sparato solo una volta:

__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

Si prega di leggere Upgrading from 3.0 to 3.1, in particolare il paragrafo Chiedere Leggi & autorizzazioni di scrittura separatamente . Sembra che Facebook SDK non sia pensato per essere usato in questo modo.

Ora è necessario richiedere l'autorizzazione di lettura e pubblicazione separatamente (e in tale ordine). Molto probabilmente, richiedi le autorizzazioni di lettura per la personalizzazione quando l'app viene avviata e l'utente effettua prima il login. Successivamente, se opportuno, la tua app può richiedere le autorizzazioni di pubblicazione quando intende pubblicare i dati su Facebook.

e

E 'importante che non si tenta di chiamare semplicemente due metodi singoli back-to-back per sostituire una delle funzioni deprecate.

Mi chiedo come sei riuscito a risolvere questo problema. A proposito, ricevo lo stesso rapporto di arresto anomalo (FBSession: non è valido per eseguire nuovamente l'autorizzazione mentre una precedente chiamata di reauthorize non è stata ancora completata).