开发者

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 :(

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜