25

I am using Core Data, and want to set an auto_increment ID as one of the fields which will be unique. Is it possible to set auto_increment in iOS using core data? Can anyone help me with a small example of how to implement this?

Below is the code through which I am inserting records in database. In the first field "id", i want to set it as auto_increment and not manually insert it.

- (NSManagedObjectContext *)managedObjectContext {
    NSManagedObjectContext *context = nil;
    id delegate = [[UIApplication sharedApplication] delegate];
    if ([delegate performSelector:@selector(managedObjectContext)]) {
        context = [delegate managedObjectContext];
    }
    return context;
}

NSManagedObjectContext *context = [self managedObjectContext];

// Create a new managed object
NSManagedObject *newObj = [NSEntityDescription insertNewObjectForEntityForName:@"Users" inManagedObjectContext:context];

[newObj setValue:[NSNumber numberWithInt:userId] forKey:@"id"];
[newObj setValue:theFileName forKey:@"Name"];
Kassym Dorsel
  • 4,773
  • 1
  • 25
  • 52
Anu Padhye
  • 615
  • 1
  • 6
  • 16
  • can you share an example of what you have tried so far? – Rachel Gallen Jun 25 '14 at 10:47
  • 1
    http://stackoverflow.com/questions/4084548/can-we-define-auto-increment-attribute-in-core-data – Rachel Gallen Jun 25 '14 at 10:49
  • I checked above link and it creates Unique ID, but not auto_increment. Does core data have anything similar to auto_increment in MySQl? – Anu Padhye Jun 25 '14 at 11:22
  • why would you need an autoincrement attribute? Most of the time in mysql it is used to get a unique key – in coredata a unique id will be managed automatically (objectID) – Alexander Jun 25 '14 at 11:50
  • 2
    If you want to sort your objects by creation add attribute storing date or unix time stamp. If you want uniqueness of your object core data already handles for you - read http://stackoverflow.com/questions/1351998/creating-a-unique-id-for-a-core-data-program-on-the-iphone – PiotrDomo Jun 25 '14 at 12:14
  • Okay! Thank you for the guidance. I wanted to store id for every user, which I have to use in the project too. This is the reason I wanted an auto_increment for id. But i have managed to do that now. :) – Anu Padhye Jun 26 '14 at 06:41

2 Answers2

32

Core Data does not have an auto-increment feature. The fact that it uses SQLite internally is mostly irrelevant-- if you focus on SQL-like details, you'll get Core Data badly wrong.

If you want an incrementing field, you'll have to manage it yourself. You can save the current value in your app's NSUserDefaults. Or you could put it in the metadata for the persistent store file that Core Data uses (see methods on NSPersistentStoreCoordinator). Either is fine, just make sure to look it up, increment it, and re-save it when you create a new object.

But you probably don't need this field. Core Data already handles unique IDs for each managed object-- see NSManagedObjectID.

Tom Harrington
  • 69,312
  • 10
  • 146
  • 170
  • 11
    Actually, I can think of one usage case here. If you're trying to track a certain Core Data object between application launches, then the `NSManagedObjectID` is not reliable, since it can change (e.g. after a data migration). Therefore, you will need to create your own unique Identifier for this, in which case an auto incrementing ID or similar is a reasonable choice. – Carlos P Jan 22 '15 at 16:08
  • 2
    That's why I said "probably". Auto increment is still probably a bad idea since any app that syncs its data (now or in the future) runs the risk of duplicates. UUIDs are likely to be safer if unique IDs are needed. – Tom Harrington Jan 22 '15 at 17:17
  • 2
    If that was why you said "probably", then you should have gone on to mention it. This is a useful implementation detail for anyone who might rely on `NSManagedObjectID` thinking that that it was a persistent ID between application launches. I agree with you about AutoIncrement, however - we also went with UUIDs in the end for that same reason. – Carlos P Jan 22 '15 at 17:31
  • 3
    I was answering a single question, not providing a detailed discussion of all possible uses of unique IDs in Core Data and the full implications of `NSManagedObjectID`. My answer explains how to accomplish the goal stated in the question. – Tom Harrington Jan 22 '15 at 17:40
  • 1
    A novel example of why you may prefer an auto-incrementing int ID rather than a UUID ID is to make the value more user presentable. For example, if you wanted to expose data via a deeplink. Such as `my-app://open/note/12` vs `my-app://open/note/HORRIBLE-LOOKING-UUID-STRING` – josh-fuggle Aug 02 '18 at 11:41
  • 2
    A much simpler user case: when order matters, and you need to keep objects in order of creation. – André Fratelli Dec 21 '20 at 15:57
-2

Here is something you can do but after saving the Entry So make sure calling saveContext() before you get that else you gonna always get zero

objective-C

- (int)getAutoIncrement:(InAppMessage*)inApp {
    int number = 0;
    NSURL *url = [[inApp objectID] URIRepresentation];
    NSString *urlString = url.absoluteString
    NSString *pN = [[urlString componentsSeparatedByString:@"/"] lastObject];
    if ([pN containsString:"p"]){
        NSString *stringPart = [pN stringByReplacingOccurrencesOfString:@"p" withString:@""]
        number = stringPart.intValue
    }
    url = nil;
    urlString = nil;
    pN = nil;
    stringPart = nil;
    return number;
}

Swift:

func getAutoIncremenet() -> Int64   {
    let url = self.objectID.uriRepresentation()
    let urlString = url.absoluteString
    if let pN = urlString.components(separatedBy: "/").last {
        let numberPart = pN.replacingOccurrences(of: "p", with: "")
        if let number = Int64(numberPart) {
            return number
        }
    }
    return 0
}
nahlamortada
  • 489
  • 6
  • 16