Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing Attribute Type in Core Data with NSInferMappingModelAutomaticallyOption

I have my Core Data Store and I use the flag 'NSInferMappingModelAutomaticallyOption' so that whenever I make changes to the Core Data Model I first create a new model version, and the changes to the data models are automatically migrated.

However, I need to change an attribute type for one of my Entities. When I do this, the automatic migration doesn't seem to work and I get a Core Data error when I try to run my app.

Any way of setting this up to continue with the automatic model migration?

like image 615
Wise Shepherd Avatar asked Jul 08 '13 19:07

Wise Shepherd


2 Answers

You cannot use lightweight migration for this so it is a little bit harder (thanks Apple), but not impossible

step by step in Xcode 7.1:

1. Create the new model version:

  1. Select your .xcdatamodeld model -> Editor -> Add model version ...
  2. Edit the new model's entity's attribute type
  3. Change current model version to the new one (File inspector). You should see the green tick mark moved.

Current model

2. Custom Core Data mapping model

  1. New file -> Mapping Model (Core Data -> Mapping Model)
  2. Choose the source (from model) and target (to model) version of your model
  3. The custom mapping model contains entities mappings called this way: NameToName. Change value expression of the changed attribute in target entity in this file reflect the one you need to: FUNCTION($entityPolicy, "<*transformingMethodName*>" , $source.<*attributeName*>)

- transformingMethodName: Your custom method that will be called to transform attribute type. (Will define it in the next step - hold on)

- attributeName: your changed attribute name

  1. Create <*EntityName*>TransformationPolicy class as a subclass of NSEntityMigrationPolicy
  2. Implement transformingMethodName you defined above. (Do what you need there to change the attribute type). Make sure you added this method to your header file as well
  3. Register this class as custom entity migration policy in the mapping model (Model.xcmappingmodel -> File inspector -> third column -> Custom policy -> Enter the name of your TransformationPolicy class.)

Register migration policy class

like image 105
Jakub Truhlář Avatar answered Oct 12 '22 12:10

Jakub Truhlář


Attribute type change is not supported by the lightweight migration:

For Core Data to be able to generate an inferred mapping model, changes must fit an obvious migration pattern, for example:

  • Simple addition of a new attribute
  • Removal of an attribute
  • A non-optional attribute becoming optional
  • An optional attribute becoming non-optional, and defining a default value
  • Renaming an entity or property

Edit

I assume you're using the lightweight migration. But as Scott pointed out, maybe you aren't. If you want to use automatic migration (which is not the same as the lightweight migration), you can still do this by providing the mapping model. In this case:

Core Data will attempt to locate the source and mapping models in the application bundles, and perform a migration.

But this migration will not be lightweight. Core Data will open two stores–the source and the target–and copy all entities in memory. So the memory consumed by the app depends on the amount of data in the store.

like image 42
eofster Avatar answered Oct 12 '22 11:10

eofster