Fastest way to get a reference to the NSMigrationManager in an automatic migration?
I have a data-heavy app and I have implemented all my CoreData migration stuff using the visual mapping models in XCode and NSEntityMigrationPolicy implementations for the cleanup code. As it turns out, the migrations on a real device are really lengthy, sometimes taking up to five minutes to complete.
I really need to give feedback to the user when this is going on, and want to KVO the migrationProgress
attribute on the NSMigrationManager. The trick is that addPersistentStoreWithType:configuration:URL:options:error:
doesn't let you get a reference to the NSMigrationManager in the event that it deems a migration to be necessary.
I discovered that I could get a reference to the NSMigrationManager by implementing the beginEntityMapping:manager:error:
callback on my custom NSEntityMigrationPolicy, starting off the observing in there.
The only issue is that by the time you get to the beginEntityMapping
call, progress seems to be up to about 30% (also, this 30% typically represents about half the total time spent inside the call to addPersistentStoreWithType
, so it's actually even worse than it s开发者_JS百科eems).
Is anyone else aware of any tricks that can be used to get a reference to the NSMigrationManager a bit earlier in proceedings so that I don't have to miss out on the first third of the opportunity to give feedback to the user about why the app is taking so long to start up?
Thanks in advance for any help!
After a few more weeks of hacking around this problem, wasn't able to find any way to achieve this and just stopped using addPersistentStoreWithType:configuration:URL:options:error:
altogether and manually triggered migration as per the documentation.
You can do it with code like this:
NSMigrationManager *migrationManager = [[NSMigrationManager alloc] initWithSourceModel:sourceModel
destinationModel:destinationModel];
//if it's set to NO, we can't migrate due to too much memory
//if it's set to YES (the default), we get no progress reporting!!
//migrationManager.usesStoreSpecificMigrationManager = NO;
NSError *mappingError;
NSMappingModel *mappingModel = [NSMappingModel inferredMappingModelForSourceModel:sourceModel
destinationModel:destinationModel
error:&mappingError];
NSPersistentStore *persistentStore;
NSError *addPersistentStoreError;
if (mappingModel) {
NSError *migrationError;
BOOL migrationSuccess = [migrationManager migrateStoreFromURL:sourceStoreURL
type:NSSQLiteStoreType
options:nil
withMappingModel:mappingModel
toDestinationURL:destinationStoreURL
destinationType:NSSQLiteStoreType
destinationOptions:nil error:&migrationError];
But take special note of -usesStoreSpecificMigrationManager
If it's YES (which you really want to have a much easier migration), you get no progress updates which is the worst catch-22 ever :(
精彩评论