Core Data Migration: Attribute Mapping Value Expression
One thing you can do is create a custom migration policy class that has a function mapping your attribute from the original value to a new value. For example I had a case where I needed to map an entity called MyItems that had a direct relationship to a set of values entities called "Items" to instead store an itemID so I could split the model across multiple stores.
The old model looked like this:
The new model looks like this:
To do this, I wrote a mapping class with a function called itemIDForItemName and it was defined as such:
@interface Migration_Policy_v1tov2 : NSEntityMigrationPolicy { NSMutableDictionary *namesToIDs;}- (NSNumber *) itemIDForItemName:(NSString *)name;@end
#import "Migration_Policy_v1tov2.h"@implementation Migration_Policy_v1tov2 - (BOOL)beginEntityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError **)error { namesToIDs = [NSMutableDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:1],@"Apples", [NSNumber numberWithInt:2],@"Bananas", [NSNumber numberWithInt:3],@"Peaches", [NSNumber numberWithInt:4],@"Pears", [NSNumber numberWithInt:5],@"Beef", [NSNumber numberWithInt:6],@"Chicken", [NSNumber numberWithInt:7],@"Fish", [NSNumber numberWithInt:8],@"Asparagus", [NSNumber numberWithInt:9],@"Potato", [NSNumber numberWithInt:10],@"Carrot",nil]; return YES; } - (NSNumber *) itemIDForItemName:(NSString *)name { NSNumber *iD = [namesToIDs objectForKey:name]; NSAssert(iD != nil,@"Error finding ID for item name:%@",name); return iD; } @end
Then for the related Mapping Name for the attribute in your mapping model you specify the Value Expression as the result of your function call as such:FUNCTION($entityPolicy,"itemIDForItemName:",$source.name)
**
You also have to set the Custom Policy Field of your Mapping Name for that attribute to your mapping class name (in this case Migration_Policy_v1tov2).
**note this should match the selector signature of the method