Simple question, I’m currently using Core Data. I have a form which is responsible for inserting a new item. If there is no category or name, save button should remains disabled. Currently, I’m doing this simple if statement in my controller, but is there any good practice about validation in iOS development?
Like in rails or any PHP MVC framework, any validations should be in the models, Would it be the same for Core data models?
Thank you.
EDIT
What I’ doing currently is I check with textFieldEditingChanged: if both of my textfield are not empty to enable the save button. When they are not empty and the user press Save, I create my new Core data object and then save it. What would you suggest according to your solution?
When a field is modified method
- (IBAction)textFieldEditingChanged:(UITextField *)textField
{
saveButton.enabled = [self validatesRequiredFields];
if (textField == descField)
{
itemDesc = descField.text;
}
else if (textField == personField)
{
personName = personField.text;
}
else if (textField == valueField)
{
itemValue = valueField.text;
}
}
Validation method
- (BOOL)validatesRequiredFields
{
if (category != nil && personField.text.length != 0)
{
return YES;
}
else
{
return NO;
}
}
When the save button is pressed method
- (IBAction)saveButtonPressed
{
item = [Item createEntity];
item.type = itemType;
item.desc = itemDesc;
item.value = itemValue;
item.imageFilename = itemImageFilename;
item.category = category;
item.addedDate = itemDueDate;
Person *p = [Person personWithName:personName];
item.person = p;
if (dueDateField)
{
item.dueDate = itemDueDate;
}
[delegate itemAddSaveButtonPressed:item];
}
EDIT 2
What I’m now using
- (BOOL)isValid
{
BOOL valid;
NSError *error;
item.type = itemType;
item.desc = itemDesc;
item.value = itemValue;
item.imageFilename = itemImageFilename;
item.category = category;
item.addedDate = itemDueDate;
if (dueDateField)
{
item.dueDate = itemDueDate;
}
if (personName.length > 0)
{
item.person = [Person personWithName:personName];
}
else
{
item.person = nil;
}
if ([item validateForInsert:&error])
valid = YES;
else
valid = NO;
return valid;
}
It’s important to distinguish between validating the managed object that will result from the form and validating the data entered into the form. Core Data will automatically validate the managed object(s) that you add to your context. Your question, though, seems to relate to validating the data entered into the form, possibly before the managed object is even created.
As you’ve described it, the state of the “save” button depends on presence of a name in one of your fields. Clearly, the view controller needs to be involved here to some degree since model objects don’t know anything about views. One way to handle this is to just let the view controller do its own validation, as you’re doing now. That’s not so bad for simple cases, and it’s the obvious route if you’ve implemented your view controller such that the managed object isn’t created until the user taps the “save” button.
Another way to do it is to have the view controller create a new managed object when its view is first displayed, and then copy any changes to the user interface over to the managed object. If you do it that way, you can use NSManagedObject’s
-validateForInsert:and/or-validateForUpdate:methods to decide whether the data in the managed object is valid, and you can set the state of the “save” button based on the result. This approach means that any validation rules for the managed object will be checked, and changing the rules for the entity won’t require also updating the validation code in the view controller.