Adding an Attribute to a Core Data Entity in Xcode 4

I wanted to add an attribute to one of the objects I manage using Core Data in my iPhone app. Because it’s a simple change, I wanted to use what Apple calls Lightweight Migration–automatically migrating the data when you make a simple change like adding a field.

I had to assemble the steps from a few different places to get it to work, partially because blog posts I found were for Xcode 3, and not even all the Apple docs have been updated for Xcode 4. Here’s the full set of steps that worked for me. For example purposes, I’m assuming your app is called YourApp, and the Core Data model is called YourData.

  1. Don’t make changes to the data model yet!
  2. Run your app in the simulator to make sure it has data set up under the current version of the entity.
  3. Select the YourData.xcdatamodel file and choose Editor > Add Model Version… The default numbering scheme (“YourData 2″) is probably fine.
  4. Select the new YourData 2.xcdatamodel file, select the entity, and add the new attribute. Make sure the right pane is visible (third button above “View” on the toolbar) and the third option within that pane is selected. Either set the attribute to be optional, or set it to have a default value–you have to choose one or the other for Lightweight Migration to work.
  5. Regenerate your model classes by selecting the entity, choosing File > New > New File…, then NSManagedObject subclass. Note: I first created my classes under Xcode 3, and at that time it put the .h and .m files inside of the actual YourData.xcdatamodel file (which is really a directory on the filesystem). Xcode 4 didn’t seem to give me this option, but that’s fine–to me, it makes more sense to store them with the other classes anyway. If you do put your new .h and .m files in a new location, be sure to delete the old ones.
  6. Select the YourData.xcdatamodeld file, go to the right panel, first option, and look for Versioned Data Model > Current Version. Set this to the newer version.
  7. In YourAppAppDelegate.m, find the persistentStoreCoordinator method, or wherever you call addPersistentStoreWithType:… You will probably be passing it nil for options:. Instead, pass this:


    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
    [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

  8. Update your app to use the new attribute/property in your entity. You might want to make only small changes at first, in case something goes wrong with your auto migration.
  9. Run your app and test it.

I wrote these steps out after I finished, so please leave a comment to let me know if I missed something and you run into other trouble.

About these ads

16 Responses to Adding an Attribute to a Core Data Entity in Xcode 4

  1. Dov says:

    Thanks for this… Really helped me out

  2. Norm says:

    XCode will not let me remove the files in the old data model. Delete is not an option in the context menu. I tried to remove them from the directory, but then Xcode complained about missing references. It seems to be taking the new ones, but I was wondering how you removed the old files?

    • Josh Justice says:

      I don’t have Xcode in front of me right now, but I think you’re referring to removing old model versions. You actually don’t need or want to do that: the app uses those to track the history, to help it upgrade if someone’s using an older version of your app. So keep both the old and new versions, and you should be set.

      • Norm says:

        No, not removing the old model version, removing the .m and .h files that were generated in Xcode 3. Generating new ones works fine, but it doesn’t let you save them in the .xcdatamodeld folder. And like you said, it makes more sense to put them somewhere else. However, I can’t remove the old .m and .h files from under the .xcdatamodeld “category” in Xcode. No delete option. When I go into the folder in finder or terminal and remove the files, Xcode complains about missing references. I can’t figure out how to get them out of my project. For now I added a #warning to the include files so that I will know if they are being included instead of my new ones.

      • Josh Justice says:

        Unfortunately, no, I haven’t run across this problem before. If anyone finds a solution, please feel free to post it to the comments here–it seems like several people have found this post when running across that problem.

  3. Caitlin says:

    Norm,

    Have you found the answer to this? i have the same problem where I cannot remove the old .h and .m from the Xcode 3 package. If I generate the new files the linker fails with duplicate symbols for these files.
    Thanks

  4. weny says:

    Hi, thanks for your tutorial! I’m quite new to objective-c programming, may I know for step 7, do I insert in like the following?

    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
    [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil error:&error]];

    I’m still getting an error near options. (Error: Expected’:’). Could you please help me with this? Thanks!

  5. Hannah says:

    The info on doing this is rather disjointed, so thanks a lot for putting these steps together. For once it wasn’t a headache to add a new attribute!

  6. Bond2875 says:

    Great work Dude helped me a lot….

  7. Bond2875 says:

    Just to add if the entity name needs to be changed then it will not work ……. Only adding and removing will work.

  8. Mesbah says:

    Thanks for putting it in one place. Really helpful.

  9. Deeps says:

    Thanks a lot buddy….this really helped me…Thanks a lot…

  10. Elias says:

    Thanks a lot dude… really helped me out..

  11. Really helpful thanks! I have to say it’s important to read carefully as this is intricate. I was reading so much I didn’t pay attention to the fact that the options dictionary you create has to also be added in as an argument in the addPersistentStoreWithType: method so it reads like I have it below.

    Not sure if others are as careless as me so dropping it in here for good measure.

    Thanks again.

    Here is
    - (NSPersistentStoreCoordinator *)persistentStoreCoordinator
    {
    if (__persistentStoreCoordinator != nil)
    {
    return __persistentStoreCoordinator;
    }

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@”Quickpace.sqlite”];

    NSError *error = nil;
    __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

    // Lightweight migration
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
    [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

    if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error])
    {
    //[[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil];

    NSLog(@”Unresolved error %@, %@”, error, [error userInfo]);
    abort();
    }

    return __persistentStoreCoordinator;
    }

  12. Symm says:

    May I know more on step 8? I’m new to core data. Not really sure what you mean by “Update your app to use the new attribute/property in your entity”. thanks!

  13. Asim says:

    This article is helpful thank.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 525 other followers

%d bloggers like this: