Saturday, September 14, 2013

Unique Auto Increment Values for NSManagedObjects (Core Data)

Auto Increment Values for NSManagedObjects

Unique Auto Increment Values for NSManagedObjects

Core Data automatically generate auto increment id for each managed object.

The unique auto id is however not exposed through the api. However, there is [NSManagedObject objectID] method that returns the unique path for each object.

Its usually in the form <x-coredata://SOME_ID/Entity/ObjectID> e.g <x-coredata://197823AB-8917-408A-AD72-3BE89F0981F0/Message/p12> for object of Message entity with ID `p12. The numeric part of the ID (last seqment of the path) is the auto increment value for each object.

Here is a method that returns the auto increment integer value for an NSManagedObject

@implementation NSManagedObject(Extra)

-(NSUInteger)autoId{

NSURL *url = [[self objectID] URIRepresentation];
//get full url
NSString *url_string = [url absoluteString];

//split with a /
NSArray *parts = [url_string componentsSeparatedByString:@"/"];

NSString *last_segment=[parts objectAtIndex:[parts count]-1];

//p#
NSString *number_part = [last_segment stringByReplacingOccurrencesOfString:@"p" withString:@""];

NSUInteger auto_id = [number_part integerValue];

number_part =nil;
last_segment=nil;
parts=nil;
url=nil;
url_string=nil;


return auto_id;

}
@end

Side Note

Do not use this method on the fly. When I first used this method in our chat app, it took much time to render the messages. I was using the auto increment value to order the messages.

To solve this, I added a new attribute to the Messages entity called auto_increment_integer. Anytime I create and save a new object, I set its auto_increment_integer value to the return value of autoId.

Like this:

    NSManagedObjectContext *localContext = [NSManagedObjectContext MR_contextForCurrentThread];

    Message *m = [Message MR_createInContext:localContext];
    //Set attributes here
    //....
    //save object
    [localContext MR_saveToPersistentStoreAndWait];

    //set the auto increment value
    m.auto_increment_id=[NSNumber numberWithInt:[m autoId]];
    //save again
    [localContext MR_saveToPersistentStoreAndWait];

Hope this helps.