1

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

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

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

有什么想法吗?

4

2 回答 2

2

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

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

2) 将新实体属性添加到此新模式版本。

3)在您的 xcdatamodeld 选项(左窗格)中将新模式版本设置为活动版本。

4)在 UIApplicationDelegate 中的 persistentStore 初始化方法中设置NSMigratePersistentStoresAutomaticallyOption和为 true。NSInferMappingModelAutomaticallyOption

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

于 2013-11-05T14:02:22.720 回答
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];

    // 检查我们是否已经有一个持久存储
    if ( [[NSFileManager defaultManager] fileExistsAtPath: [storeURL path]] ) {
        NSDictionary *existingPersistentStoreMetadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType: NSSQLiteStoreType URL: storeURL error: &error];
        如果(!existingPersistentStoreMetadata){
            // 持久存储发生了*真的*糟糕的事情
            //[NSException raise: NSInternalInconsistencyException format: @"Failed to read metadata for persistent store %@: %@", storeURL, error];
            NSLog(@"读取持久存储 %@ 的元数据失败:%@", storeURL, error);
        }

        if ( ![managedObjectModel isConfiguration: nil compatibleWithStoreMetadata: existingPersistentStoreMetadata] ) {
            if ( ![[NSFileManager defaultManager] removeItemAtURL: storeURL error: &error] )
                NSLog(@"*** 无法删除持久化存储,%@", 错误);
        } // 否则现有的持久存储与当前模型兼容 - 很好!
    } // 否则还没有数据库文件

    [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                                              配置:无
                                                        网址:商店网址
                                                    选项:无
                                                      错误:&错误];
    返回_persistentStoreCoordinator;
}

此代码涵盖问题

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

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

于 2013-11-05T15:00:14.267 回答