Core Data unique attributes

I've decided to use the validate<key>:error: method to check if there is already a Managed Object with the specific value of <key>. An error is raised if this is the case.

For example:

- (BOOL)validateMyAttribute:(id *)value error:(NSError **)error {
    // Return NO if there is already an object with a myAtribute of value
}

Thanks to Martin Cote for his input.


From IOS 9 there is a new way to handle unique constraints.

You define the unique attributes in the data model.

You need to set a managed context merge policy "Merge policy singleton objects that define standard ways to handle conflicts during a save operation" NSErrorMergePolicy is the default,This policy causes a save to fail if there are any merge conflicts.

- (NSManagedObjectContext *)managedObjectContext {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.)
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (!coordinator) {
        return nil;
    }
  _managedObjectContext = [[NSManagedObjectContext alloc]    initWithConcurrencyType:NSMainQueueConcurrencyType];
  [_managedObjectContext setPersistentStoreCoordinator:coordinator];
  [_managedObjectContext setMergePolicy:NSOverwriteMergePolicy];
    return _managedObjectContext;
}

The various option are discussed at Apple Ducumentation Merge Policy

It is answered nicely here Zachary Orr's Answer

and he has kindly also created a blogpost and sample code.

Sample Code

Blog Post

The most challenging part is to get the data Model attributes editable.The Secret is to left click and then right click, after you have clicked the + sign to add a constraint.

enter image description here


Every time i create on object I perform a class method that makes a new Entity only when another one does not exist.

+ (TZUser *)userWithUniqueUserId:(NSString *)uniqueUserId inManagedObjectContext:(NSManagedObjectContext *)context
{
    TZUser *user = nil;
    NSFetchRequest *request = [[NSFetchRequest alloc] init];

    request.entity = [NSEntityDescription entityForName:@"TZUser" inManagedObjectContext:context];
    request.predicate = [NSPredicate predicateWithFormat:@"objectId = %@", uniqueUserId];
    NSError *executeFetchError = nil;
    user = [[context executeFetchRequest:request error:&executeFetchError] lastObject];

    if (executeFetchError) {
         NSLog(@"[%@, %@] error looking up user with id: %i with error: %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), [uniqueUserId intValue], [executeFetchError localizedDescription]);
    } else if (!user) {
        user = [NSEntityDescription insertNewObjectForEntityForName:@"TZUser" 
                                             inManagedObjectContext:context];
    }

    return user;
}