0

This is my Sign In button :

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

And this is my alreadyRegisteredPhoneNumber method, where I am just checking if the given phone number is registered or not.

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

With this method the problem is that the activityIndicator is not appearing when I press Sign In button. Otherwise it works synchronize way, which is perfect.

The reason activityIndicator is not appearing is that I have to update UI related change in dispatch_async(dispatch_get_main_queue() (Or not??). But If I rearrange my code like this :

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

The activityIndicator is showing perfectly, but it always return isThisPhoneNumberRegistered = NO, because it works asynchronize way, where my update isThisPhoneNumberRegistered = YES return lately.

So If I want, this scenario where:

  1. User press Sign In button
  2. Then the activityIndicator shows up
  3. My server call (strongSelf.userModelClass = [[RetrieveDataClass class] retrieveUserInfoForPhoneNumber:PhoneNumberWithIsoCountryCode];) retrieve data and set isThisPhoneNumberRegistered = YES or isThisPhoneNumberRegistered = NO according to it
  4. Then return the value to 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];
    
    }
    

How can I do it?
A lot of Thanks in advance.

1
  • Why do you need any queue or activity-indicator within the alreadyRegisteredPhoneNumber-method? As far as I can see all these code is called withing the main thread. Commented May 1, 2017 at 16:29

1 Answer 1

1

In general, you want to use Asynch processes so you can "do other stuff" such as updating the UI to let the user know something is going on.

In order to do that, you need to separate your logic. Try to think of it in these terms:

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
}

In other words, don't write your code so it gets "locked into" a process, preventing anything else from happening.

Sign up to request clarification or add additional context in comments.

1 Comment

All I need is to call two separate method in dispatch_asyn response. With my BOOL isThisPhoneNumberRegistered can't be done, I guess. It's working now. Thanks mate.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.