If you look in the Data Model inspector you'll see a field marked "Constraints" – click the + button at the bottom of that field. A new row will appear saying "comma,separated,properties". Click on that, hit Enter to make it editable, then type "sha" and hit Enter again. Make sure you press Cmd+S to save your changes!
You can think of attributes as the columns of a table in a database. Attributes store the values of a Core Data record. There are several types of attributes, such as String, Date, Integer, Float, and Boolean. Select the Note entity in the data model editor and click the + button at the bottom of the Attributes table.
Save. Unique Constraints are a way to declare a custom attribute to be unique across all instances of an entity. Its intended use case is the import of external data that should be merged with existing objects in the database.
An NSManagedObject instance implements the basic behavior required of a Core Data model object. The NSManagedObject instance requires two elements: an entity description (an NSEntityDescription instance) and a managed object context (an NSManagedObjectContext instance).
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;
}
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.
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.
You could override the setMyAttribute
method (using categories) and ensure uniqueness right there, although this may be expensive:
- (void)setMyAttribute:(id)value
{
NSArray *objects = [self fetchObjectsWithMyValueEqualTo:value];
if( [objects count] > 0 ) // ... throw some exception
[self setValue:value forKey:@"myAttribute"];
}
If you want to make sure that every MyEntity
instance has a distinct myAttribute
value, you can use the objectID
of the NSManagedObject
objects for that matter.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With