iBull
iBull

Reputation: 65

Why is my code being ran backwards? Or so it seems?

I have an IBAction that when called, registers a user information with Parse.com... I have only implemented the email and username methods, since i need to make sure that prior to submission to the server i added a counter int, if the counter == 2 it will execute the registration... well to my surprise, when I run the code, it gets ran backwards, so my conditional statement at the bottom is not even reviewed, why is this the case?

This is my code:

- (IBAction)signMeUpButton:(id)sender {
    [self.view endEditing:YES];
    counter = 0;



    user = [PFUser user];

    NSString *emailFromTextField = self.emailTF.text;

    if ([self isValidEmailAddress:emailFromTextField]) {


    [self emailHasBeenTaken:emailFromTextField completion:^(BOOL emailIsTaken, NSError *error) {
        if (error) {
            // TODO: handle any errors here
            return;
        }

        if (!emailIsTaken) {
            emailString = emailFromTextField;
            user.email = emailString;
            counter++;
            NSLog(@"The email is %@ the counter is %i", emailString, counter);

        }
        else {
            [self duplicateEmail];
        }
    }];


    }

    NSString *usernameFromTextField = self.usernameTF.text;
    if (usernameFromTextField.length >= 1) {
        [self usernameHasBeenTaken:usernameFromTextField completion:^(BOOL usernameIsTaken, NSError *error) {
            if (error) {
                return;
            }

            if (!usernameIsTaken) {
                usernameString = usernameFromTextField;
                user.username = usernameString;
                counter++;
                NSLog(@"The username is %@ and the counter is %i", usernameString, counter);
            }
            else {
                //
            }
        }];
    }

    if (counter == 2) {
        NSLog(@"Its working");
    }
}

And this is what I get on my console when i run it, as you can see the usernameHasBeenTaken is being called FIRST, even though I have it written second... why is that?

2014-07-17 23:18:12.169 app[28210:60b] in the usernameHasBeenTaken. USERNAME IS NOT EXISTENT
2014-07-17 23:18:12.170 app[28210:60b] The username is sample and the counter is 1
2014-07-17 23:18:15.328 app[28210:60b] in the emailHasBeenTaken, EMAIL IS NOT EXISTENT
2014-07-17 23:18:15.328 app[28210:60b] The email is [email protected] the counter is 2

These are my 2 methods: usernameHasBeenTaken and emailHasBeenTaken

- (void)emailHasBeenTaken:(NSString *)email completion:(void(^)(BOOL emailIsTaken, NSError *error))completionBlock
{
    void (^completionCopy)(BOOL, NSError *) = [completionBlock copy];

    PFQuery *query = [PFUser query];
    [query whereKey:@"email" equalTo:email];

    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {

        if (error) {
            NSLog(@"in the emailHasbeenTaken ERROR HAS OCCURRED");
            if (completionCopy) {
                completionCopy(NO, error);
            }
            return;
        }

        if (objects.count > 0) {
            NSLog(@"in the emailHasbeenTaken EMAIL IS DUPLICATE");
            if (completionCopy) {
                completionCopy(YES, nil);
            }
        }
        else {
            NSLog(@"in the emailHasBeenTaken, EMAIL IS NOT EXISTENT");
            if (completionCopy) {
                completionCopy(NO, nil);
            }
        }
    }];
}

- (void) usernameHasBeenTaken:(NSString *)username completion:(void(^)(BOOL usernameIsTaken, NSError *error))completionBlock
{
    void (^completionCopy)(BOOL, NSError *) = [completionBlock copy];
    PFQuery *query = [PFUser query];
    [query whereKey:@"username" equalTo:username];

    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if (error) {
            NSLog(@"in the usernameHasBeenTaken ERROR HAS OCCURED");
            if (completionCopy) {
                completionCopy(NO, error);
            }
            return;
        }

        if (objects.count > 0) {
            NSLog(@"in the usernameHasBeenTaken USERNAME IS DUPLICATE");
            if (completionCopy) {
                completionCopy(NO, nil);
            }
        }
        else {
            NSLog(@"in the usernameHasBeenTaken. USERNAME IS NOT EXISTENT");
            if (completionCopy) {
                completionCopy(NO, nil);
            }
        }
    }];
}

Upvotes: 0

Views: 73

Answers (1)

Johnathon Sullinger
Johnathon Sullinger

Reputation: 7414

Your use of a completion block indicates that you are running them asynchronously. If that is the case then your password condition gets hit immediately after you invoke emailHasBeenTaken:completion:

If you must run async, which you should if you are hitting a web service, you need to nest your calls in the completion blocks.

Edit

It appears that this is the case. The Parse API runs async, to avoid locking the UI thread. You will need to nest your callbacks like I show below.

- (IBAction)signMeUpButton:(id)sender {
    [self.view endEditing:YES];
    counter = 0;



    user = [PFUser user];

    NSString *emailFromTextField = self.emailTF.text;

    if ([self isValidEmailAddress:emailFromTextField]) {


    [self emailHasBeenTaken:emailFromTextField completion:^(BOOL emailIsTaken, NSError *error) {
        if (error) {
            // TODO: handle any errors here
            return;
        }

        if (!emailIsTaken) {
            emailString = emailFromTextField;
            user.email = emailString;
            counter++;
            NSLog(@"The email is %@ the counter is %i", emailString, counter);

            NSString *usernameFromTextField = self.usernameTF.text;
            if (usernameFromTextField.length >= 1) {
                [self usernameHasBeenTaken:usernameFromTextField completion:^(BOOL usernameIsTaken, NSError *error) {
                    if (error) {
                        return;
                    }

                if (!usernameIsTaken) {
                    usernameString = usernameFromTextField;
                    user.username = usernameString;
                    counter++;
                    NSLog(@"The username is %@ and the counter is %i", usernameString, counter);
            }
            else {
                //
            }

            if (counter == 2) {
                NSLog(@"Its working");
            }
        }];
    }
        }
        else {
            [self duplicateEmail];
        }
    }];


    }
}

Upvotes: 2

Related Questions