Core Date migration


Steve Mills
 

In my Core Data model, I've added a 2nd version with a new attribute. This attribute needs to be initialized to a sequential value upon migration from the old version. So I'm using a mapping model and a custom migration policy to set this new attribute's value on every entity object.

But, it's not sticking. Do I need to be doing something else in my performCustomValidationForEntityMapping:manager:error: method to cause the changes I've made to be saved? Or am I just interpreting the incredibly vague documentation for this method wrong?

-(BOOL) performCustomValidationForEntityMapping:(NSEntityMapping*)mapping manager:(NSMigrationManager*)manager error:(NSError* _Nullable __autoreleasing*)error
{
BOOL result = YES;

if([manager isKindOfClass:[DocumentMigrationManager class]]) {
Document* doc = ((DocumentMigrationManager*)manager).doc;
NSFetchRequest* fetchRequest = [NSFetchRequest new];
NSEntityDescription* assetEntDesc = [Asset entityInManagedObjectContext:manager.destinationContext];

fetchRequest.entity = assetEntDesc;

NSArray<Asset*>* asses = [manager.destinationContext executeFetchRequest:fetchRequest error:error];

for(Asset* ass in asses) {
// ass.order = @(doc.nextAssetOrder);
[ass setValue:@(doc.nextAssetOrder) forKey:AssetAttributes.order];
}
}

return result;
}

(And damn it, when is Mail going to let us change to 4 spaces per tab like *normal* people use? My radar for that has been ignored for years.)

--
Steve Mills
Drummer, Mac geek


Jim
 

On Jul 22, 2019, at 8:56 AM, Steve Mills via Groups.Io <sjmills@...> wrote:

In my Core Data model, I've added a 2nd version with a new attribute. This attribute needs to be initialized to a sequential value upon migration from the old version. So I'm using a mapping model and a custom migration policy to set this new attribute's value on every entity object.

But, it's not sticking. Do I need to be doing something else in my performCustomValidationForEntityMapping:manager:error: method to cause the changes I've made to be saved? Or am I just interpreting the incredibly vague documentation for this method wrong?

-(BOOL) performCustomValidationForEntityMapping:(NSEntityMapping*)mapping manager:(NSMigrationManager*)manager error:(NSError* _Nullable __autoreleasing*)error
{
BOOL result = YES;

if([manager isKindOfClass:[DocumentMigrationManager class]]) {
Document* doc = ((DocumentMigrationManager*)manager).doc;
NSFetchRequest* fetchRequest = [NSFetchRequest new];
NSEntityDescription* assetEntDesc = [Asset entityInManagedObjectContext:manager.destinationContext];

fetchRequest.entity = assetEntDesc;

NSArray<Asset*>* asses = [manager.destinationContext executeFetchRequest:fetchRequest error:error];

for(Asset* ass in asses) {
// ass.order = @(doc.nextAssetOrder);
[ass setValue:@(doc.nextAssetOrder) forKey:AssetAttributes.order];
}
}

return result;
}
Do you call save on the context somewhere? I’ve not needed to use a mapping like this yet but it seems like if you’re changing attributes you’d want to save.

Jim Crate


Steve Mills
 

On Jul 23, 2019, at 12:54:04, Jim <jimcfl@...> wrote:

Do you call save on the context somewhere? I’ve not needed to use a mapping like this yet but it seems like if you’re changing attributes you’d want to save.
No, I wasn't sure if that was necessary. One would hope that the act of migration will save the migrated data to the store without the developer having to do anything. It doesn't say that in the migration doc. In fact, it says it's part of the default migration process:

https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreDataVersioning/Articles/vmMigrationProcess.html#//apple_ref/doc/uid/TP40004399-CH6-SW8

I've also gone the "normal" route of creating the new objects in configurePersistentStoreCoordinatorForURL:ofType:modelConfiguration:storeOptions:error: and setting the new attribute's value there. Both ways work at that point in the migration, but then when addPersistentStoreWithType:configuration:URL:options:error: is called at the end, it once again goes through another migration that I expect would happen. My custom migration policy is created out of my control, so I can't set a custom property on it, nor can I add an object to any object's userInfo (NSEntityMapping, NSMigrationManager, etc). I need to be able to get back to my document from the migration policy, and I can't find a way to do that when the default migration happens. If I could, then I don't think I'd need to do the manual migration at all.

--
Steve Mills
Drummer, Mac geek


Dave Fernandes
 

If you are modifying the object, I believe you should be doing this in:
createDestinationInstances(forSource:in:manager:)

This has always worked for me. The validation method looks like a keep/don’t keep decision point, though I have never used it.


On Jul 22, 2019, at 11:56 AM, Steve Mills via Groups.Io <sjmills@...> wrote:

In my Core Data model, I've added a 2nd version with a new attribute. This attribute needs to be initialized to a sequential value upon migration from the old version. So I'm using a mapping model and a custom migration policy to set this new attribute's value on every entity object.

But, it's not sticking. Do I need to be doing something else in my performCustomValidationForEntityMapping:manager:error: method to cause the changes I've made to be saved? Or am I just interpreting the incredibly vague documentation for this method wrong?

-(BOOL) performCustomValidationForEntityMapping:(NSEntityMapping*)mapping manager:(NSMigrationManager*)manager error:(NSError* _Nullable __autoreleasing*)error
{
BOOL result = YES;

if([manager isKindOfClass:[DocumentMigrationManager class]]) {
Document* doc = ((DocumentMigrationManager*)manager).doc;
NSFetchRequest* fetchRequest = [NSFetchRequest new];
NSEntityDescription* assetEntDesc = [Asset entityInManagedObjectContext:manager.destinationContext];

fetchRequest.entity = assetEntDesc;

NSArray<Asset*>* asses = [manager.destinationContext executeFetchRequest:fetchRequest error:error];

for(Asset* ass in asses) {
// ass.order = @(doc.nextAssetOrder);
[ass setValue:@(doc.nextAssetOrder) forKey:AssetAttributes.order];
}
}

return result;
}

(And damn it, when is Mail going to let us change to 4 spaces per tab like *normal* people use? My radar for that has been ignored for years.)

--
Steve Mills
Drummer, Mac geek