views:

20

answers:

1

I've implemented a small proof-of-concept app using Core Data to accept some object attribute values from the user via text fields and it's all working great thanks to information found here and in the iPhone Core Data Recipes app. But I'm at the point where I need to display object validation errors to the user and I can't find a recommended way of handling this. The code in the Recipe app just logs the error and says to "Replace this implementation with code to handle the error appropriately." Great, thanks.

I'm sure there are a multitude of ways to interpret, parse and transmit the validation error information to the user but what I'd like to know is if there are some best practices or a pattern that someone has implemented that I could follow. Where should the validation code like [newObject valdiateForInsert&error]; be placed? In NSManagedObject subclasses? In the UIViewController that handles the screen the enables the object to be added? Maybe in an app-wide ValidationController?

All the validation errors are returned in the NSError's userInfo, which is a NSDictionary of various NSValidation keys and values. Is there a good way of translating this error info into something that would be helpful to the user? For example, I have a rule in my Core Data model that a certain attribute can only be 3 characters long. If in the process of saving or updating an object I get a validation error, I need to parse out the NSError userInfo and find values for the NSValidationErrorKey (the name of the attribute), the NSValidationErrorValue (the value on the object that caused the error) and the NSValidationErrorPredicate (the rule that was violated, which in this case returns length <= 3.

Is there a good, generally accepted way of gathering and munging this data into something that can be passed back to the user? I'm currently pulling the NSError info into strings and then falling through a series of conditional statements for each attribute that I'm validating, and it's so ugly that I kinda want to puke when I look at it. There has to be a better, cleaner way to consume Core Data validation errors and pass a readable version to the user.

+2  A: 

Validations are not there for the user. They are there so the code can maintain the integrity of the object graph. Validation methods are not called by the managed object context until the time at which context is saved. That time might be very distant from the time of input.

However, you can call an objects validation methods directly before you set an attribute. The validation methods have the form:

- (BOOL)validateTimeStamp:(id *)valueRef error:(NSError **)outError;

Suppose you have an attribute name for a managed object subclass PeopleMO. The validation method to check for an empty string might look like:

- (BOOL)validateName:(id *)valueRef error:(NSError **)outError{
    BOOL isValid=NO;
    NSString *toTest=(NSString *) valueRef;
    if (![toTest isEqualToString:@""]) {
        isValid=YES;
    }
    return isValid;
}

You could call it anywhere like:

NSString *newName=// some UI element text 
PersonMO *newPerson=//.. insert new PersonMO object
if ([newPerson validateName:newName error:nil]) {
    newPerson.name=newName;
}else{
    //... inform user name is invalid
    // ... possibly delete newPerson object from context
}

This is most useful where you have situations in which the validity of the value of one attribute depends on one or more other attributes of the same object.

TechZen
My goal is to not duplicate validation checking if I don't have to. If I set up the xcdatamodel so that an attribute is required or has min/max length values or requires only numbers, then I'd like to be able to use Core Data's validateForInsert and validateForUpdate methods to do all that validation checking for me. I can consume any NSError object passed back from them and parse it out so I can give the end user the information they need to correct their input values. I was just looking for a good/standard/efficient/accepted way to accomplish this.
ScottS