【发布时间】:2018-04-01 03:04:36
【问题描述】:
我们的应用需要 Core Data 轻量级迁移,因为我们向实体添加了一些属性。
在 TestFlight 上向我们的 Beta 测试人员发布更新后,我们收到了其中一些人的报告,称该应用在启动时崩溃了。在获得崩溃日志后,我们意识到跳板看门狗正在杀死应用程序,因为迁移时间过长。
在网上搜索资源后,似乎可以通过首先检查是否需要迁移,而不涉及核心数据堆栈,然后选择在另一个视图中进行迁移来卸载 application:didFinishLaunchingWithOptions: 之外的迁移控制器。这是我想要做的:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if ([[ZSSCoreDataManager sharedService] migrationRequired]) {
UpgradeDatabaseViewController *upgrade = [self.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:@"UpgradeDatabaseViewController"];
self.window.rootViewController = upgrade;
}
return YES;
}
迁移测试:
- (BOOL)migrationRequired {
NSManagedObjectModel *mom = [NSManagedObjectModel mergedModelFromBundles:nil];
NSPersistentStoreCoordinator *persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
NSError *error = nil;
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreDataMergeTest.sqlite"];
// Determine if a migration is needed
NSDictionary *sourceMetadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType URL:storeURL options:nil error:&error];
NSManagedObjectModel *destinationModel = [persistentStoreCoordinator managedObjectModel];
BOOL pscCompatibile = [destinationModel isConfiguration:nil compatibleWithStoreMetadata:sourceMetadata];
return !pscCompatibile;
}
升级DatabaseViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(@"Starting migration");
// Start migration by accessing th epersistent container
[[ZSSCoreDataManager sharedService] persistentContainer];
NSLog(@"Ended migration");
UIWindow *window = [UIApplication sharedApplication].keyWindow;
UINavigationController *nav = [self.storyboard instantiateViewControllerWithIdentifier:@"MainNav"];
window.rootViewController = nav;
}
持久化容器:
- (NSPersistentContainer *)persistentContainer {
@synchronized (self) {
if (_persistentContainer != nil) {
return _persistentContainer;
}
_persistentContainer = [[NSPersistentContainer alloc] initWithName:@"Model"];
// Store description
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreDataMergeTest.sqlite"];
NSPersistentStoreDescription *description = [NSPersistentStoreDescription persistentStoreDescriptionWithURL:storeURL];
description.shouldInferMappingModelAutomatically = YES;
description.shouldMigrateStoreAutomatically = YES;
description.type = NSSQLiteStoreType;
_persistentContainer.persistentStoreDescriptions = @[description];
[_persistentContainer loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription *storeDescription, NSError *error){
if (error != nil) {
NSLog(@"Unresolved error %@, %@", error, error.userInfo);
//abort();
}
}];
_persistentContainer.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
_persistentContainer.viewContext.undoManager = nil; // We don't need undo so set it to nil.
_persistentContainer.viewContext.shouldDeleteInaccessibleFaults = YES;
_persistentContainer.viewContext.automaticallyMergesChangesFromParent = YES;
}
return _persistentContainer;
}
遗憾的是,这似乎仍未解决问题,因为跳板仍会终止应用程序(当设备未插入且调试器正在运行时)。
这里有什么我做错了吗?不管我们是否不初始化数据库,轻量级迁移是否发生在application:didFinishLaunchingWithOptions:?
是否可以在使用轻量级迁移时做我想做的事情?
【问题讨论】:
标签: ios objective-c core-data core-data-migration