使用下一个App版本更新Core Data + iCloud模型

时间:2014-06-23 12:31:36

标签: ios core-data migration upgrade icloud

我必须处理使用Core Data和iCloud的下一个应用程序版本。 iCloud已在当前版本中使用最现代化的#34;方式:

if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
                                                   configuration:@"data_cfg"
                                                             URL:storeURL
                                                         options:@{NSPersistentStoreUbiquitousContentNameKey:@"theStore"}
                                                           error:&error]) 

现在我需要更新添加新实体,关系等的商店结构......

我完全陷入困境,因为我不知道更新模型的更好方式是知道iCloud与用户数据同步。

执行此类更新的最佳方式是哪种?我应该注意什么以及我最应该注意什么?如何迁移当前数据?

2 个答案:

答案 0 :(得分:5)

使用iCloud时更新模型与不使用iCloud时相同 - 唯一的例外是您的更改必须是自动轻量级迁移的更改。 Apple's documentation详细描述了此类迁移的要求。基本步骤是:

  1. 创建数据模型的新版本,并使此版本"当前"。 (你必须保留旧模型,所以现在你有两个,但只有一个是最新的。)
  2. 在新版本中更改模型。
  3. NSMigratePersistentStoresAutomaticallyOptionNSInferMappingModelAutomaticallyOption添加到上面代码中的选项词典中,使用@YES作为两者的值。
  4. 现在,当您启动应用程序时,Core Data将比较模型的旧版本和新版本(假设您的更改适用于自动轻量级迁移)修改持久性存储以使用新版本。

    请记住,iCloud同步仅适用于使用相同版本数据模型的设备。如果用户在一台设备上升级您的应用程序而不是他们使用的另一台设备,则同步将停止,直到他们在其他设备上升级该应用程序。

答案 1 :(得分:5)

iCloud Backup并不重要,顺便说一下这里是安装新sqlite模型的解决方案。 如果可以从服务器重新创建/下载应用程序内的数据,那么有一个很好的解决方案。 您不需要设置迁移堆栈,有一个非常快速的解决方案。诀窍是删除旧的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文件名,它会正常工作。

如果您的数据无法重新创建(与服务器同步),则需要设置迁移堆栈 这里是Apple的指南https://developer.apple.com/library/mac/Documentation/Cocoa/Conceptual/CoreDataVersioning/CoreDataVersioning.pdf

的链接