2017-02-10 82 views
0

我需要用我的應用程序登錄Facebook,獲取一些數據,並在完成後登錄到Firebase。我正在使用派遣隊列,但它不起作用。我的街區並不等待對方完成。串口調度隊列不等待

這裏是我的代碼:

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

任何想法?謝謝!

+1

Facebook登錄和火力點登錄本身是異步的,所以你的異步分派塊退出而異步登錄仍在運行。在這裏看到我的解釋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

謝謝!我讀過它,但恐怕我還是不明白......請看我編輯的答案! –

+0

你不想第一個等待;當您想阻止上一個任務的等待完成時,您只需要等待。你仍然需要你的dispatch_async,否則你會阻止主線程等待。你也可以使用dispatch_group_notify,因爲這兩個操作是獨立的,你只是想知道兩者何時完成。 – Paulw11

回答

2

撥打電話爲Facebook完成處理器內的火力地堡登陸,它將作爲一切工作的預期

+0

謝謝!但我試圖避免嵌套塊 –

1

雖然你在一個串行調度隊列調度異步任務,這些任務自身上調度異步任務和然後結束;所以你的任務已經完成,但登錄沒有。

正如@Rob建議的那樣,使用諸如NSOperation之類的代碼將代碼拆分爲單獨的任務將會產生更清晰,更具可伸縮性的代碼。

然而,這裏是你如何使用dispatch_groupdispatch_group_notify安排一些代碼,當異步操作完成:

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