这是我的应用程序中的当前初始化代码,基于Paul Hegarty的cs193p:
UIManagedDocument *database = nil;
if (!database) {
NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
url = [url URLByAppendingPathComponent:@"stdDatabase"];
database = [[UIManagedDocument alloc] initWithFileURL:url];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
database.persistentStoreOptions = options;
}
if (![[NSFileManager defaultManager] fileExistsAtPath:[database.fileURL path]]){
[database saveToURL:database.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success){
completionBlock(database);
}];
} else if (database.documentState == UIDocumentStateClosed){
[database openWithCompletionHandler:^(BOOL success){
completionBlock(database);
}];
} else if (database.documentState == UIDocumentStateNormal) {
completionBlock(database);
}
这是我想要使用的新初始化代码,基于Marcus Zarra撰写的“核心数据”一书:
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"Corrida_de_Leitos" withExtension:@"momd"];
ZAssert(modelURL, @"Failed to find model URL");
NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
ZAssert(mom, @"Failed to initialize model");
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:mom];
ZAssert(psc, @"Failed to initialize persistent store coordinator");
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[moc setPersistentStoreCoordinator:psc];
[self setManagedObjectContext:moc];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL *storeURL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
storeURL = [storeURL URLByAppendingPathComponent:@"stdDatabase"];
NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setValue:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setValue:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
NSError *error = nil;
NSPersistentStoreCoordinator *coordinator = [moc persistentStoreCoordinator];
NSPersistentStore *store = [coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error];
if (!store) {
NSLog(@"Error adding persistent store to coordinator %@\nUSERINFO:\n%@", [error localizedDescription], [error userInfo]);
}
dispatch_sync(dispatch_get_main_queue(), ^{
[self contextInitialized];
});
});
这是我将商店添加到协调员时遇到的错误:
'Error adding persistent store to coordinator The operation couldn’t be completed. (Cocoa error 256.)
USERINFO:
{
NSSQLiteErrorDomain = 14;
NSUnderlyingException = "unable to open database file";
}'
如何修复新代码以便能够打开旧数据库文件?
答案 0 :(得分:2)
UIManagedDocument将在UIManagedDocument包(目录)中创建此sqlite文件,因此您需要获取原始sqlite文件的URL并将其用作新版本应用程序中的URL,如有必要,请使用NSFileManager将文件移动到另一个位置,但这不是必需的。请参阅UIManagedDocument的示例目录结构,一个用于本地,一个用于iCloud同步存储。如果它不是iOS7则检查,因为结构/名称可能不同。
理论上,您可以从UIManagedDocument.persistentStoreName
获取实际的商店文件名,只需将其附加到UIManagedDocument.fileURL
- 但实际上这省略了我认为的StoreContent
子目录。
通常UIManagedDocument
会在"stdDatabase/StoreContent/persistentStore"
创建文件。但是要确保在模拟器中运行应用程序的原始版本,然后确切地检查用于创建存储文件的路径。
只要您使用相同的选项打开,实际的sqlite文件就可以正常工作。
答案 1 :(得分:-1)
问题是UIManagedDocument
为您创建堆栈并使用与SQLite文件不兼容的格式保存数据库文件,如果您想使用首先迁移存储的SQLite文件(文件) ,NSPersistentStoreCoordinator
有一个名为migratePersistentStore:toURL:options:withType:error:
的方法可以执行此迁移。