2017-02-10 4 views
0

Je dois me connecter à Facebook avec mon application, aller chercher des données et APRÈS ceci, connectez-vous également à Firebase. J'utilise les files d'attente d'expédition pour cela mais cela ne fonctionne pas. Mes blocs n'attendent pas les uns les autres pour finir.La file d'attente d'expédition en série n'attend pas

Voici mon code:

dispatch_queue_t loginQueue = dispatch_queue_create("com.balazsvincze.loginQueue", DISPATCH_QUEUE_SERIAL); 


//Log in to Facebook 
    dispatch_async(loginQueue, ^{ 
     FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init]; 
     [login logInWithReadPermissions: @[@"public_profile",@"user_friends"] fromViewController:viewController handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { 

      if(!error){ 
       NSLog(@"Logged into Facebook"); 
       self.facebookUserID = [[FBSDKAccessToken currentAccessToken] userID]; 

       //Load my profile 
       [FBSDKProfile loadCurrentProfileWithCompletion:^(FBSDKProfile *profile, NSError *error){ 
        if(!error){ 
         self.name = profile.name; 
        } 

        else{ 
         NSLog(@"Could not load profile: %@",error); 
         completionResult(NO); 
         return; 
        } 

       }]; 
      } 

      else{ 
       NSLog(@"Could not login: %@",error); 
       completionResult(NO); 
       return; 
      } 

     }]; 
    }); 

    //Log in to Firebase 
    dispatch_async(loginQueue, ^{ 
     FIRAuthCredential *credential = [FIRFacebookAuthProvider credentialWithAccessToken:[FBSDKAccessToken currentAccessToken].tokenString]; 

     [[FIRAuth auth] signInWithCredential:credential completion:^(FIRUser *user, NSError *error) { 

      if(!error){ 
       NSLog(@"Logged into Firebase"); 
       self.firebaseUserID = user.uid; 
      } 

      else{ 
       NSLog(@"Could not login: %@",error); 
       completionResult(NO); 
       return; 
      } 
     }]; 
    }); 

Toutes les idées? Merci!

+1

Le login Facebook et les connexions Firebase eux-mêmes sont asynchrones, de sorte que votre async a envoyé des blocs de sortie tandis que les connexions asynchrones sont toujours en cours d'exécution. Voir mon explication ici http://stackoverflow.com/questions/42145427/how-does-a-serial-queue-private-dispatch-queue-know-when-a-task-is-complete/42146095?noredirect=1# comment71500175_42146095 – Paulw11

+0

Merci! Je l'ai lu mais j'ai peur que je ne comprends toujours pas ... S'il vous plaît voir ma réponse éditée! –

+0

Vous ne voulez pas la première attente; vous ne voulez qu'une attente lorsque vous voulez bloquer l'achèvement de la tâche précédente. Vous avez toujours besoin de votre dispatch_async ou vous allez bloquer le thread principal sur l'attente. vous pouvez aussi utiliser un dispatch_group_notify car les deux opérations sont indépendantes et vous voulez juste savoir quand les deux sont terminées. – Paulw11

Répondre

2

font l'appel à se connecter à Firebase dans le gestionnaire d'achèvement Facebook, et cela va fonctionner comme prévu

+0

Merci! Mais j'essayais d'éviter les blocs de nidification –

1

Bien que vous dispatching des tâches asynchrones sur une file d'attente d'envoi série, ces tâches se sont expédiées tâches asynchrones et puis fin; Vos tâches sont donc terminées, mais pas les connexions. Comme suggéré par @Rob, la division de votre code en tâches distinctes en utilisant quelque chose comme NSOperation donnera un code plus propre et plus évolutif.

Cependant, voici comment vous pouvez utiliser un dispatch_group et dispatch_group_notify pour planifier un code lorsque les opérations asynchrones ont terminé:

dispatch_group_t dispatchGroup = dispatch_group_create(); 

//Log in to Facebook 
dispatch_group_enter(dispatchGroup); 

FBSDKLoginManager *login = [[FBSDKLoginManager alloc] init]; 
[login logInWithReadPermissions: @[@"public_profile",@"user_friends"] fromViewController:viewController handler:^(FBSDKLoginManagerLoginResult *result, NSError *error) { 

    if(!error){ 
     NSLog(@"Logged into Facebook"); 
     self.facebookUserID = [[FBSDKAccessToken currentAccessToken] userID]; 

     //Load my profile 
     dispatch_group_enter(dispatchGroup); 
     [FBSDKProfile loadCurrentProfileWithCompletion:^(FBSDKProfile *profile, NSError *error){ 
      if(!error){ 
       self.name = profile.name; 
      } 
      else{ 
       NSLog(@"Could not load profile: %@",error); 
       completionResult(NO); 
      } 
      dispatch_group_leave(dispatchGroup); 
     }]; 
    } 
    else{ 
     NSLog(@"Could not login: %@",error); 
     completionResult(NO); 
    } 
    dispatch_group_leave(dispatchGroup); 
}]; 

//Log in to Firebase 
dispatch_group_enter(dispatchGroup); 

FIRAuthCredential *credential = [FIRFacebookAuthProvider credentialWithAccessToken:[FBSDKAccessToken currentAccessToken].tokenString]; 

[[FIRAuth auth] signInWithCredential:credential completion:^(FIRUser *user, NSError *error) { 

    if(!error){ 
     NSLog(@"Logged into Firebase"); 
     self.firebaseUserID = user.uid; 
    } 

    else{ 
     NSLog(@"Could not login: %@",error); 
     completionResult(NO); 
    } 
    dispatch_group_leave(dispatchGroup); 
}]; 

dispatch_group_notify(dispatchGroup,dispatch_get_main_queue(),^{ 
    NSLog(@"All login tasks completed"); 
    // Do whatever 
});