Search code examples
iphonecore-dataxcode4

Auto-Incremented Object ID in Core Data?


I am working with several NSManagedObject types with several relationships. How can I tell Core Data to automatically populate object IDs for me? I'm looking for something like an index key in SQL, so that no two instances of a given object are allowed to have the same ID.

Edit:

I'd like for all of my "Account" objects to have unique IDs on them. I was just adding one to the `countForFetchRequest, but I realized that when deleting the second to last object and then adding one, the last two objects now have the same IDs.

How can I ensure that a given value has a unique value for all instances of my "Account" NSManagedObject?

EDIT2:

I need to have a separate ID for sorting purposes.


Solution

  • The way I resolved this is with Core Data aggregates. I actually end up assigning the ID myself.

    Essentially, I query Core Data for all of the entity IDs of my entity and then iterate through them. If I find an ID which is higher than the current temporary one, I make the temporary ID higher one higher than the aggregated one. When I'm done, I automatically have an ID which is higher than the highest one in the list. The only flaw I see with this is if there is a missing ID. (I believe that there is a simple fix for this as well.)

    //
    //  Create a new entity description
    //
    
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"MyEntity" inManagedObjectContext:self.managedObjectContext];
    
    //
    //  Set the fetch request
    //
    
    NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
    [fetchRequest setEntity:entity];
    
    //
    //  We need to figure out how many 
    //  existing groups there are so that 
    //  we can set the proper ID.
    //
    //  To do so, we use an aggregated request.
    //
    
    [fetchRequest setResultType:NSDictionaryResultType];
    [fetchRequest setPropertiesToFetch:[NSArray arrayWithObject:@"entityID"]];
    
    NSError *error = nil;
    
    NSArray *existingIDs = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
    
    
    if (error != nil) {
    
        //
        //  TODO: Handle error.
        //
    
        NSLog(@"Error: %@", [error localizedDescription]);
    }
    
    NSInteger newID = 0;
    
    for (NSDictionary *dict in existingIDs) {
        NSInteger IDToCompare = [[dict valueForKey:@"entityID"] integerValue];
    
        if (IDToCompare >= newID) {
            newID = IDToCompare + 1;
        }
    } 
    
    //
    //  Create the actual entity
    //
    
    MyEntity *newEntity = [[MyEntity alloc] initWithEntity:entity insertIntoManagedObjectContext:self.managedObjectContext];
    
    //
    //  Set the ID of the new entity
    //
    
    [newEntity setEntityID:[NSNumber numberWithInteger:newID]];
    
    //
    //   ... More Code ...
    //