这是我的应用程序中基于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撰写的“Core Data”一书:
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";
}'

如何修复新代码,以便能够打开旧数据库文件?

最佳答案

UIManagedDocument将在UIManagedDocument包(目录)中创建此sqlite文件,因此您需要获取原始sqlite文件的URL,并将其用作应用程序新版本中的URL,如有必要,请使用NSFileManager移动文件到另一个位置,但这并不是必须的。请参阅UIManagedDocument中的示例目录结构,一种用于本地,另一种用于iCloud同步存储。如果不是iOS7,则检查其结构/名称可能不同。

从理论上讲,您可以从UIManagedDocument.persistentStoreName获取实际的商店文件名,然后将其简单地附加到UIManagedDocument.fileURL-但实际上,这忽略了我认为的StoreContent子目录。

通常UIManagedDocument会在"stdDatabase/StoreContent/persistentStore"处创建文件。但是,请确保在模拟器中运行应用程序的原始版本,然后准确检查用于创建商店文件的路径。

只要使用相同的选项打开,实际的sqlite文件就可以正常工作。

关于ios - 更改核心数据的初始化方式后,数据库将无法打开,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20313321/

10-10 20:45