Search code examples
core-dataios7nsmanagedobjectcontextmagicalrecord

Context Saving issue in Magical record Core data during custom validation


I have created an entity named "Person". Following are the attributes of entity.

@property (nonatomic, retain) NSString * address;
@property (nonatomic, retain) NSString * confirmPassword;
@property (nonatomic, retain) NSString * createdOn;
@property (nonatomic, retain) NSString * email;
@property (nonatomic, retain) NSString * fbId;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSString * password;
@property (nonatomic, retain) NSString * phNumber;
@property (nonatomic, retain) NSString * sessionToken;

Custom Validation is added on two attributes "confirmPassword" and "password" like:

- (BOOL)validatePassword:(id *)ioValue error:(NSError **)outError {

    // Password's validation is not specified in the model editor, it's specified here.
    // field width: min 4, max 32

    BOOL isValid = YES;
    NSString *password = *ioValue;
    NSString *errorMessage;
    NSInteger code = 0;

    if (password.length == 0) {

        errorMessage = @"Please enter password.";
        code = NSValidationMissingMandatoryPropertyError;
        isValid = NO;

    } else if (password.length < 4) {

        errorMessage = @"Password can't be less than 4 characters.";
        code = NSValidationStringTooLongError;
        isValid = NO;

    } else if (password.length > 32) {

        errorMessage = @"Password can't be more than 32 characters.";
        code = NSValidationStringTooLongError;
        isValid = NO;

    }

    if (outError && errorMessage) {
        NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : errorMessage };
        NSError *error = [[NSError alloc] initWithDomain:kHAB
                                                    code:code
                                                userInfo:userInfo];
        *outError = error;
    }

    return isValid;

}

- (BOOL)validateConfirmPassword:(id *)ioValue error:(NSError **)outError {

    // Confirm Password's validation is not specified in the model editor, it's specified here.
    // field validation
    BOOL isValid = YES;
    NSString *confirmPassword = *ioValue;
    NSString *errorMessage;
    NSInteger code = 0;
    if (![confirmPassword isEqualToString:self.password]) {
        errorMessage = @"The passwords must match";
        code = NSValidationStringPatternMatchingError;
        isValid = NO;
    }
    if (outError && errorMessage) {
        NSDictionary *userInfo = @{ NSLocalizedDescriptionKey : errorMessage };
        NSError *error = [[NSError alloc] initWithDomain:kHAB
                                                    code:code
                                                userInfo:userInfo];
        *outError = error;
    }
    return isValid;
}

Values are being saved in Person entity like:

Person  *userProfile = [Person MR_createEntity];
NSString *facebookId = @"some id";
[userProfile setFbId:facebookId];
[userProfile setEmail:@"umairsuraj.engineer@gmail.com"];
[[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait];

It fails to save context saying person entity doesn't pass a valid validation of password and confirm password fields. I do not need to enter password and confirm password fields during sign up from Facebook. what should i do to save context without saving values for "password" and "confirmPassword".?


Solution

  • It seems pretty straightforward:

    • Your class Person includes validation methods for the password and confirmPassword fields. These methods do not accept nil values.
    • You created an instance of Person but did not set a value for password. The new instance therefore has a nil value for this field.
    • You attempt to save changes.

    In short, verification fails because your own verification code requires it to fail. For verification to pass, you must either assign a valid value for password (where "valid" means something that your code will accept) or change the validation code so that a nil value passes validation.

    It's not clear what Facebook has to do with this question. Nothing in your code seems to relate to Facebook in any way.