How to make a special check (for uniqueness) in Core Data?

I have an object in Core Data that has an attribute that must be unique. It is not possible to set this in the visual interface. I assume that I need to create my own class that inherits from NSManagedObject, and then write my own validation method.

I successfully created a custom class by selecting objects in the visual editor and choosing File → New → New File → Subclass NSManagedObject. I use this to add creation timestamps, so I know this works.

But what now? What methods do I need?

The NSManagedObject reference manual tells me to "implement validate: error: form methods," but does not provide an example.

Similar questions here and here , but I need more help.

A complete example would be awesome, but any help is greatly appreciated.

+7
source share
3 answers

This does the trick, although on bulk inserts it is slow and you still need to create an NSError object.

-(BOOL)validateValue:(__autoreleasing id *)value forKey:(NSString *)key error:(NSError *__autoreleasing *)error { [super validateValue:value forKey:key error:error]; // Validate uniqueness of my_unique_id if([key isEqualToString:@"my_unique_id"]) { NSFetchRequest * fetch = [[NSFetchRequest alloc] init]; [fetch setEntity:[NSEntityDescription entityForName:[self.entity name] inManagedObjectContext:self.managedObjectContext]]; NSPredicate *predicate = [NSPredicate predicateWithFormat:@"my_unique_id = %@",[self valueForKey:key]]; fetch.predicate = predicate; NSError *error = nil; NSUInteger count = [self.managedObjectContext countForFetchRequest:fetch error:&error]; if (count > 1) { // Produce error message... // Failed validation: return NO; } } return YES; } 
+2
source

Say you have a foo property that you want to check

From Property Level Verification :

If you want to implement logic in addition to the restrictions that you provide in the managed object model, you should not override validateValue:forKey:error: Instead, you should implement the methods of the form validate<Key>:error:

Where <Key> is your property. You would really implement something like:

 -(BOOL)validateFoo:(id *)ioValue error:(NSError **)outError { return [self isUnique]; } 
+6
source

validateValue mentioned below will do the validation trick (and the right place to validate)

If you are using NSFetchedResultsController , be sure to remove the object from memory to avoid duplicating the object in the UITableView even if an error occurs. Something like that:

 CustomManagedObject *obj = [NSEntityDescription insertNewObjectForEntityForName:@"<YourEntity>" inManagedObjectContext:self.managedObjectContext]; obj.property = @"some property"; if (![self.managedObjectContext save:&error]) { [self.managedObjectContext deleteObject:obj]; // delete from memory. Otherwise, you get duplicated value in UITableView even if save has failed } 
+1
source

All Articles