0

Ceci est mon Connexion bouton:Mise à jour l'interface utilisateur (activityIndicator) dans dispatch_sync file d'attente (Objective C)

- (IBAction)signInButtonAction:(id)sender 
{ 
    if ([self.phoneNumberTextField.text length] == 0 || [self.passwordTextField.text length] == 0) { 
     [self initializeAlertControllerForOneButtonWithTitle:@"Alert!" withMessage:kEmptyTextFieldAlertMSG withYesButtonTitle:@"Ok" withYesButtonAction:nil]; 

    } else { 
     if ([self alreadyRegisteredPhoneNumber] == YES) { 
      if ([self.password isEqualToString:self.passwordTextField.text]) { 
       [self goToHomeViewController]; 

      } else { 
       [self initializeAlertControllerForOneButtonWithTitle:@"Wrong Password!" withMessage:kWrongPasswordMSG withYesButtonTitle:@"Ok" withYesButtonAction:nil]; 

      } 

     } else { 
      [self initializeAlertControllerForOneButtonWithTitle:@"Alert!" withMessage:kSignInPhoneNumberDoesnotExistMSG withYesButtonTitle:@"Ok" withYesButtonAction:nil]; 
     } 
    } 
} 

Et voici ma alreadyRegisteredPhoneNumber méthode, où je suis en train de vérifier si le numéro de téléphone donné est enregistré ou non.

- (BOOL)alreadyRegisteredPhoneNumber 
{ 
    [self.activityIndicator startAnimating]; 
    __block BOOL isThisPhoneNumberRegistered = NO; 

    BlockWeakSelf weakSelf = self; 
    SignInViewController *strongSelf = weakSelf; 

    dispatch_sync(dispatch_queue_create("mySyncQueue", NULL), ^{ 
     NSString *PhoneNumberWithIsoCountryCode = [NSString stringWithFormat:@"%@%@", strongSelf.countryCode, strongSelf.phoneNumberTextField.text]; 
     strongSelf.userModelClass = [[RetrieveDataClass class] retrieveUserInfoForPhoneNumber:PhoneNumberWithIsoCountryCode]; 
     if ([strongSelf.userModelClass.phone_number length] != 0) { 
      strongSelf.phoneNumber = strongSelf.userModelClass.phone_number; 
      strongSelf.password = strongSelf.userModelClass.password; 
      isThisPhoneNumberRegistered = YES; 
      [strongSelf.activityIndicator stopAnimating]; 
     } 
    }); 

    return isThisPhoneNumberRegistered; 
} 

Avec cette méthode, le problème est que le activityIndicator ne comparaît pas quand je presse bouton Connexion. Sinon, cela fonctionne de façon synchronisée, ce qui est parfait.

La raison activityIndicator n'apparaît pas est que je dois mettre à jour la modification liée à l'interface utilisateur dans dispatch_async(dispatch_get_main_queue() (Ou pas ??). Mais si je réarrange mon code comme ceci:

- (BOOL)alreadyRegisteredPhoneNumber 
{ 
    [self.activityIndicator startAnimating]; 
    __block BOOL isThisPhoneNumberRegistered = NO; 

    BlockWeakSelf weakSelf = self; 
    SignInViewController *strongSelf = weakSelf; 

    dispatch_async(dispatch_get_main_queue(), ^{ 

     dispatch_sync(dispatch_queue_create("mySyncQueue", NULL), ^{ 
      NSString *PhoneNumberWithIsoCountryCode = [NSString stringWithFormat:@"%@%@", strongSelf.countryCode, strongSelf.phoneNumberTextField.text]; 
      strongSelf.userModelClass = [[RetrieveDataClass class] retrieveUserInfoForPhoneNumber:PhoneNumberWithIsoCountryCode]; 
      if ([strongSelf.userModelClass.phone_number length] != 0) { 
       strongSelf.phoneNumber = strongSelf.userModelClass.phone_number; 
       strongSelf.password = strongSelf.userModelClass.password; 
       isThisPhoneNumberRegistered = YES; 
       [strongSelf.activityIndicator stopAnimating]; 
      } 
     }); 
    }); 

    return isThisPhoneNumberRegistered; 
} 

Le activityIndicator est montrant parfaitement, mais toujours retourner isThisPhoneNumberRegistered = NO, parce que cela fonctionne asynchronize façon, où ma mise à jour isThisPhoneNumberRegistered = YES retour ces derniers temps.

Donc, si je veux, ce scénario où:

  1. utilisateur presse Connexion bouton
  2. Ensuite, la activityIndicator apparaît
  3. Mon appel serveur (strongSelf.userModelClass = [[RetrieveDataClass class] retrieveUserInfoForPhoneNumber:PhoneNumberWithIsoCountryCode];) récupérer les données et définir isThisPhoneNumberRegistered = YES ou isThisPhoneNumberRegistered = NO selon
  4. Ensuite, renvoyer la valeur à If else condition

    if ([self alreadyRegisteredPhoneNumber] == YES) { 
         if ([self.password isEqualToString:self.passwordTextField.text]) { 
          [self goToHomeViewController]; 
    
    } else { 
          [self initializeAlertControllerForOneButtonWithTitle:@"Wrong Password!" withMessage:kWrongPasswordMSG withYesButtonTitle:@"Ok" withYesButtonAction:nil]; 
    
    } 
    

Comment puis-je faire?
Un grand merci d'avance.

+0

Pourquoi avez-vous besoin d'une file d'attente ou d'un indicateur d'activité dans la méthode 'alreadyRegisteredPhoneNumber'? Autant que je peux voir tous ces codes s'appellent avec le fil principal. –

Répondre

1

En général, vous voulez pour utiliser les processus Asynch afin de pouvoir "faire d'autres choses" telles que la mise à jour de l'interface utilisateur pour informer l'utilisateur que quelque chose se passe.

Pour ce faire, vous devez séparer votre logique. Essayez de penser en ces termes:

signInButtonAction { 
    if no phone or password entered 
     show alert 
    else 
     showAnimatedSpinner() 
     checkForRegisteredPhone() 
} 

checkForRegisteredPhone { 
    // start your async check phone number process 
    // on return from the async call, 
    if !registered 
     hide spinner 
     show kSignInPhoneNumberDoesnotExistMSG message 
    else 
     checkForMatchingPassword() 
} 

checkForMatchingPassword { 
    if !passwordsMatch 
     hide spinner 
     show "passwords don't match" message 
    else 
     hide spinner 
     goToHomeViewController 
} 

En d'autres termes, ne pas écrire votre code de sorte qu'il se « enfermé dans » un processus, ce qui empêche toute autre chose de se produire.

+0

Tout ce dont j'ai besoin est d'appeler deux méthodes séparées dans la réponse 'dispatch_asyn'. Avec mon 'BOOL isThisPhoneNumberRegistered' ne peut pas être fait, je suppose. Ça marche maintenant. Merci mon pote. – Tulon