[SOLVED I HOPE] Re: Core Data Versioning: Non-trivial Value Expressions?
[SOLVED I HOPE] Re: Core Data Versioning: Non-trivial Value Expressions?
- Subject: [SOLVED I HOPE] Re: Core Data Versioning: Non-trivial Value Expressions?
- From: Jerry Krinock <email@hidden>
- Date: Tue, 4 May 2010 10:00:41 -0700
On 2010 May 04, at 03:50, Chaitanya Pandit wrote:
> Core Data ... migration process ... not that hard
Don't often see those words together in the same paragraph, but it is straightforward, thanks to Chaitanya.
I did spend a couple more fruitless hours trying to understand the Core Data Model Versioning and Data Migration Programming Guide before I got it. So I've added a few more details and some changes to make it easier for the next dummy...
> To start with you create a subclass of NSEntityMigrationPolicy to say MyMigrationPolicy.
MyMigrationPolicy can handle custom migrations for different entities. Therefore if you were writing a migration from versions 2 to 3 you might call this class MyDocument2_3MigrationPolicy. Add this class to your project.
> Now in your mapping model specify "MyMigrationPolicy" as the "Custom Policy" for attribute you wish to manage in a custom way.
Actually this goes in the Entity, not the Attribute.
In more detail, create a mapping model in Xcode in the usual way and open it in the Xcode editor. In the "Entity Mappings" table, select an entity which requires custom migration of one or more attributes (because the required Value Expression is non-trivial). In the detail view, in the "Custom Policy" field, fill in your migration policy class name, i.e. MyMigrationPolicy. Repeat if there are any more such entities.
> Now implement the method:
> - (BOOL)createDestinationInstancesForSourceInstance:entityMapping:manager:error:
> In your MyMigrationPolicy class and deal with only the entities that you're interested in.
>
> A sample implementation would look something like:
Thank you!! It would have taken me days to figure all that out.
I made a few simplifications, though. When I first ran your code, an exception raised when it tried to migrate an NSNull, which it had obtained from the dictionary returned by -[NSManagedObject committedValuesForKeys:nil], into the new object. This was because of a type mismatch, NSNull != NSWhatever. So instead of using -commmittedValuesForKeys:, I used -valueForKey:, which returns nil in this case, and so -setValue:forKey:doesn't complain. I also used Fast Enumeration. Like this:
for (NSString* key in [[[inSourceInstance entity] attributesByName] allKeys])
{
id oldValue = [inSourceInstance valueForKey:key] ;
...
Here is the complete class code in case anyone is interested.
Attachment:
SampleMigrationPolicy.zip
Description: Zip archive
Although I'm still walking on tiptoes, so far Core Data has not issued any of those dreaded inexplicable exceptions from the Bowels of Migration.
Maybe it's solved.
One thing I don't understand, though...
> Using just the mapping model seems okay if your Core Data) Model is simple, but most likely it would bloat over time and the best thing to do would be to customize the migration process.
Since I don't know any alternative to what I did, I don't know what would be more bloaty. I still had to add a new mapping model. Maybe you are referring to the fact that Core Data's built-in migration process is not smart enough to concatenate migrations and therefore requires mappings from all previous versions to the current version, as explained here:
http://sunflower.coleharbour.ca/cocoamondo/2009/06/core-data-migration/
But I didn't do anything today to solve that problem.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden