5

I'm quite new to Core Data. My understanding is that it's an object graph manager, and that differs from a database. In that, some functionalities are to be implemented by the programmer.

Before writing some logic that has a better and more optimized counterpart in the coredata framework: Is it possible to add unique keys? Like entityA.name=@"jem", entityB.name=@"jem", fail to insert entityB due to a name already in use?

thanks :-) Jem.

Jem
  • 6,226
  • 14
  • 56
  • 74

2 Answers2

10

Apple Core Data Documentation

Core Data is very much a database, the GUI you use to set up the entities and attributes is only part of it. I do not believe there is already functionality for rejecting non-unique keys, but you could do something like this to run a check before inserting the new entity:

NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDescription];
BOOL unique = YES;
NSError  *error;
NSArray *items = [managedObjectContext executeFetchRequest:request error:&error];
if(items.count > 0){
    for(Person *thisPerson in items){
        if([thisItem.name isEqualToString: nameToEnter]){
             unique = NO;
        }
    }
}
if(unique){
     CartItem *thisItem = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:self.managedObjectContext];


     thisItem.name = nameToEnter;
     NSError *error;
     if (![self.managedObjectContext save:&error]) {
           return;
     }
}

and you should be good

jacerate
  • 456
  • 3
  • 8
  • 7
    It would be better to just use NSPredicate on your fetch request and only fetch for objects that have that name, instead of fetching all of the objects and iterating through them like you are here. – Mark Leonard Jul 12 '12 at 22:45
  • 4
    You can also use the `countForFetchRequest:error` method with an exact predicate to return the number of objects that match, i.e. `==1` if it already exists. – Rory O'Bryan Jul 13 '12 at 08:40
  • 1
    Just to be absolutely clear, Core Data is *not* a database. SQLite (what Core Data commonly uses), however, is. https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdTechnologyOverview.html#//apple_ref/doc/uid/TP40009296-SW1 – Chris Morris May 03 '15 at 05:55
1

Similar to the one above, but in the object code as a validation method. Thus we isolate it from the main code:

-(BOOL)validateForInsert:(NSError **)error {
  if (![super validateForInsert:error]) {
    NSLog(@"Validate for insert FALSE: %@", *error);
    return NO;
  }

  return [self validateConsistency:error];
}

-(BOOL)validateForUpdate:(NSError **)error {
  if (![super validateForUpdate:error]) {
    NSLog(@"Validate for update FALSE: %@", *error);
    return NO;
  }

  return [self validateConsistency:error];
}


-(BOOL)validateConsistency:(NSError **)error {

  // Count number of names
  NSArray *accounts = [Account whereFormat:@"name == '%@'", self.name];
  if ([accounts count] > 1) {
    // Error!

Note: I used ObjectiveRecord, but I trust that you know how to count your records.

Yer00n
  • 123
  • 1
  • 8