I'm about to do some Core Data Migration and if someone with actual experience could look this over and comment I'd appreciate the help.
I have a Core Data model with 2 entities: DataSource and DataKind. It looks like this:
.
This is all happy, but now I need to have 2 associated IP Address/Ports per data source. I think creating a new version is the right way to go, so I've added a version to the core data model, extracted a couple of attributes and the relationship from DataSource into a new entity, Connection; version 2 of the model looks like this:
.
Nothing too exciting here EXCEPT the migration process. I've read through the meager documentation and done a lot of web searching. I don't believe I can do the "simple" migration because of the new stuff, so I've written a custom migration policy subclass to do the work. Here's that code (in class DataSourceToDataSource2):
I've added in a line of code to associate the newly created connection object for later use in this code (which isn't done yet):
See, that doesn't really do anything yet. I think sInstances will have 1 object: the original DataSource object. From that, I need to find the 2 associated destination objects: DataSource and Connection. I can link those pretty easily. The one I'm struggling with is connecting the Connection object with a new DataKind object. By the time this gets called, the new DataKind destination object should be created and populated with its attributes. I think I can find it using another call to destinationInstancesForEntityMappingNamed:sourceInstances: using the original DataSource's kind link as the source instance. I can then link those up, but I'm frustrated by the lack of documentation in this area. Can someone with actual experience using Core Data Migration comment on this approach. I'm going to give it a whirl in a few minutes and will know first hand what happens (or have some idea about what happens), but it feels pretty iffy right now...
EDIT: Well, I've made some progress but now I'm stumped. The code got changed to create a NSMigrationManager that I populate with the mappingModel I created. I've tracked the problem back to versionHash mismatches between the managed object model and the mappingModel. I can' t seem to figure out how to make them match... Any thoughts?
I have a Core Data model with 2 entities: DataSource and DataKind. It looks like this:

This is all happy, but now I need to have 2 associated IP Address/Ports per data source. I think creating a new version is the right way to go, so I've added a version to the core data model, extracted a couple of attributes and the relationship from DataSource into a new entity, Connection; version 2 of the model looks like this:

Nothing too exciting here EXCEPT the migration process. I've read through the meager documentation and done a lot of web searching. I don't believe I can do the "simple" migration because of the new stuff, so I've written a custom migration policy subclass to do the work. Here's that code (in class DataSourceToDataSource2):
Code:
- (BOOL)createDestinationInstancesForSourceInstance:(NSManagedObject *)sInstance
entityMapping:(NSEntityMapping *)mapping
manager:(NSMigrationManager *)manager
error:(NSError **)error
{
// Create the Connection object from the existing DataSource object
NSManagedObject *connection = [NSEntityDescription insertNewObjectForEntityForName:@"Connection"
inManagedObjectContext:[manager destinationContext]];
[connection setValue:[sInstance valueForKey:@"ipAddress"]
forKey:@"ipAddress"];
[connection setValue:[sInstance valueForKey:@"ipPort"]
forKey:@"ipPort"];
NSManagedObject *dataSource = [NSEntityDescription insertNewObjectForEntityForName:@"DataSource"
inManagedObjectContext:[manager destinationContext]];
[dataSource setValue:[sInstance valueForKey:@"name"]
forKey:@"name"];
// Set up the association between the source and destination objects for the migration manager
[manager associateSourceInstance:sInstance withDestinationInstance:dataSource forEntityMapping:mapping];
// Do I want to do this too?
[manager associateSourceInstance:sInstance withDestinationInstance:connection forEntityMapping:mapping];
return YES;
}
I've added in a line of code to associate the newly created connection object for later use in this code (which isn't done yet):
Code:
-(BOOL)createRelationshipsForDestinationInstance:(NSManagedObject *)dInstance
entityMapping:(NSEntityMapping *)mapping
manager:(NSMigrationManager *)manager
error:(NSError *__autoreleasing *)error
{
// Create the associations among the new objects, using the hints from prior steps.
// 1. Find original source object
NSArray *sInstances = [manager sourceInstancesForEntityMappingNamed:mapping.name
destinationInstances:[NSArray arrayWithObject:dInstance]];
return YES;
}
See, that doesn't really do anything yet. I think sInstances will have 1 object: the original DataSource object. From that, I need to find the 2 associated destination objects: DataSource and Connection. I can link those pretty easily. The one I'm struggling with is connecting the Connection object with a new DataKind object. By the time this gets called, the new DataKind destination object should be created and populated with its attributes. I think I can find it using another call to destinationInstancesForEntityMappingNamed:sourceInstances: using the original DataSource's kind link as the source instance. I can then link those up, but I'm frustrated by the lack of documentation in this area. Can someone with actual experience using Core Data Migration comment on this approach. I'm going to give it a whirl in a few minutes and will know first hand what happens (or have some idea about what happens), but it feels pretty iffy right now...
EDIT: Well, I've made some progress but now I'm stumped. The code got changed to create a NSMigrationManager that I populate with the mappingModel I created. I've tracked the problem back to versionHash mismatches between the managed object model and the mappingModel. I can' t seem to figure out how to make them match... Any thoughts?
Last edited: