Reputation: 6045
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;
}
Upvotes: 3
Views: 3021
Reputation: 125007
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.
Upvotes: 4
Reputation: 7439
I think you got it right with your assumption it should work like Rails.
The easiest way to perform validation is to insert it directly in your data model description. Then, at runtime, you can use validation methods to check if the object is valid and enable/disable buttons consequently (with validateForUpdate: for instance).
If validation options inside the data model directly does not fit your needs, then you'll probably need to subclass NSManagedObject and perform some custom validation in this class, cf. "Validation Methods" paragraph here: https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/CoreDataFramework/Classes/NSManagedObject_Class/Reference/NSManagedObject.html
To make it short, in terms of architecture:
Hope it helps.
Upvotes: 3
Reputation: 13192
The encouraged practice is to subclass or extend (via categories) the generated managed objects where you can add additional functionality including data validation.
Upvotes: 3