应用程序更新后的Coredata

时间:2013-11-05 13:49:56

标签: ios core-data

我正在尝试为我的应用程序实现一个流程,以便在需要时更新应用程序,并且使用更新我的意思是在设备中加载新的应用程序.ipa。

问题是我正在使用CoreData来存储第一次启动时带来的服务器数据,而在旧版本和新版本之间我已经为数据库添加了一些实体和属性。这就产生了冲突,因为我不知道如何处理迁移和/或任何可以让我在结构发生变化时重新创建数据库的东西。

现在,如果我使用相同的数据库结构更新应用程序,该应用程序可以正常工作,但如果我修改它,应用程序会崩溃,如预期的那样。

有什么想法吗?

2 个答案:

答案 0 :(得分:2)

如果您只添加了一些实体/属性,则可以使用CoreData轻量级迁移:

1)在您打开xcdatamodeld文件的情况下,从编辑器菜单中添加新版本的架构。

2)将新实体属性添加到此新架构版本。

3)在xcdatamodeld选项(左侧窗格)中将新架构版本设置为活动版本。

4)在UIApplicationDelegate的persistentStore初始化方法中将NSMigratePersistentStoresAutomaticallyOptionNSInferMappingModelAutomaticallyOption设置为true。

您现在应该可以运行该应用。应自动更新架构以匹配新的数据库结构。这也将保留数据库内容,清空它可能是您想要在代码中执行的操作,检测到新版本的首次启动。

答案 1 :(得分:2)

如果可以从服务器重新创建/下载应用程序内的数据,那么有一个很好的解决方案。 据我所知,您正在从服务器获取数据,这是一个很好的例子,这意味着可以在新数据库中重新创建旧数据。 您不需要设置迁移堆栈,有一个非常快速的解决方案。诀窍是删除旧的sqlite数据库并创建一个新数据库。

以下是我在应用程序更新时使用的代码。 您需要在AppDelegate.m

中添加它
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"YourDatabase.sqlite"];
    NSManagedObjectModel *managedObjectModel = [self managedObjectModel];
    NSError *error = nil;
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: managedObjectModel];

    // Check if we already have a persistent store
    if ( [[NSFileManager defaultManager] fileExistsAtPath: [storeURL path]] ) {
        NSDictionary *existingPersistentStoreMetadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType: NSSQLiteStoreType URL: storeURL error: &error];
        if ( !existingPersistentStoreMetadata ) {
            // Something *really* bad has happened to the persistent store
            //[NSException raise: NSInternalInconsistencyException format: @"Failed to read metadata for persistent store %@: %@", storeURL, error];
            NSLog(@"Failed to read metadata for persistent store %@: %@", storeURL, error);
        }

        if ( ![managedObjectModel isConfiguration: nil compatibleWithStoreMetadata: existingPersistentStoreMetadata] ) {
            if ( ![[NSFileManager defaultManager] removeItemAtURL: storeURL error: &error] )
                NSLog(@"*** Could not delete persistent store, %@", error);
        } // else the existing persistent store is compatible with the current model - nice!
    } // else no database file yet

    [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                                              configuration:nil
                                                        URL:storeURL
                                                    options:nil
                                                      error:&error];
    return _persistentStoreCoordinator;
}

此代码涵盖问题

  • 如果现有数据库是旧数据库,则删除并设置新数据库。
  • 如果还没有数据库(用户只下载最新版本)而不是创建新数据库。
  • 如果现有数据库与新数据库兼容,只需使用它。

只需将@“YourDatabase.sqlite”更改为您的sqliteDB文件名,它就能正常工作。