Core data 支持iCloud的核心数据应用中的数据快照?

Core data 支持iCloud的核心数据应用中的数据快照?,core-data,icloud,snapshot,Core Data,Icloud,Snapshot,我的应用程序通过iCloud同步和备份数据(我正为此使用)。由于我的应用程序处理用户创建的重要数据,我希望通过不时创建快照(稍后可以恢复)来提供额外的安全网 我说的不是撤销一个或两个单独的更改,而是真正的快照,加上时间戳并以保存方式存储 由于我正在利用iCloud sync,我不能简单地交换应用程序中使用的sqlite存储。我想我必须删除当前上下文中的每个对象,创建从快照恢复的对象并保存上下文。然后,设备也会将更改推送到iCloud 我想到了以下场景: 该应用程序工作正常,没有创建快照的选项(这

我的应用程序通过iCloud同步和备份数据(我正为此使用)。由于我的应用程序处理用户创建的重要数据,我希望通过不时创建快照(稍后可以恢复)来提供额外的安全网

我说的不是撤销一个或两个单独的更改,而是真正的快照,加上时间戳并以保存方式存储

由于我正在利用iCloud sync,我不能简单地交换应用程序中使用的sqlite存储。我想我必须删除当前上下文中的每个对象,创建从快照恢复的对象并保存上下文。然后,设备也会将更改推送到iCloud

我想到了以下场景:

  • 该应用程序工作正常,没有创建快照的选项(这只是用户可选的安全功能)
  • 如果用户不时选择创建快照,则会要求用户输入其Dropbox登录凭据(已实现)
  • 有时,我的应用程序会创建一个后台线程,其中会设置第二个商店和第二个MOC(以及第二个PSC?)。每个对象及其关系都会复制到第二个MOC中。第二个MOC被保存,持久存储将被复制到Dropbox,线程将结束
  • 如果用户希望恢复快照并放弃创建快照后所做的所有更改,我的应用程序将反向执行第3点中所述的操作来重建数据
  • 有什么想法吗?这是要保存的吗?是否有需要考虑的注意事项(特别是与iCloud一起)?有人用类似的方式做过吗


    编辑:

    通过上述步骤,我成功地创建了商店的副本。在最初的几次尝试中,商店的娱乐活动似乎也奏效了。但是,我仍然担心加载存储文件的方式(将旧文件拖走,然后用保存的文件替换)

    然而,我遇到了苹果的“另存为…”或“重新定位”方法

    这将删除所有与iCloud关联的元数据,还将从协调器中删除当前存储(我不希望这样),并将新创建的存储添加到PSC中(我也不希望这样)


    更好的方法是什么?我当前的方法还是苹果内置的“另存为…/重新定位”?我的重点是在以后加载快照,无论iCloud是否启用。

    我觉得你的基本方法不错。我还使用了iCloudCoreDataStack,我认为这是一个健壮的解决方案

    我不明白,如果要保存一个新的存储,为什么要遍历所有对象并重新创建它们。只需保存所有内容、锁定存储、制作本地副本、解锁存储(用户现在可以继续工作),然后将存储复制到DropBox。还原时,使用下载的存储覆盖现有存储(如果在同一设备上,并且沙盒仍然存在,则无需下载)。此时,您可能还需要重置iCloud存储


    这就是说,如果您已经在遍历对象图,那么您可以使用它来做一些额外的事情,这些事情可能会很有用。您可以将整个对象图转换为JSON,并将其存储为文本文件(如果没有可转换或二进制属性)。您的数据现在可以以更多的方式和更多的平台被人类读取和使用。

    我当前允许用户使用“文件另存为”菜单选项在OS X上创建任何核心数据文件的备份副本,这使用migratePersistentStore API创建新副本,而不使用iCloud选项。当然,如果文件尚未存储在iCloud中,则不需要这样做,用户可以使用文件管理器复制文件。在iOS设备上,您将使用相同的方法,只是您需要编写自己的文件管理器来复制任何文件,因此使用migratePersistentStore API来创建新文件可能更容易。为了恢复需要迁移到iCloud的文件,不能将其复制回去。看看这个链接,我在这里发布了一些解释和示例代码,以及一些视频,展示了当用户更改其iCloud首选项设置时,文件如何在iCloud中移动和移出。此应用程序是一个基于文档的应用程序,因此允许创建多个文档,只需在FileListViewController上添加一个弹出菜单,即可将文件备份到您选择的位置


    我还一直在寻找一种解决方案,允许我的用户执行备份快照。我无法使用migratePersistentStore,因为它在过程中删除了我的活动存储。然后,我想知道是否可以将存储添加到另一个PSC,然后将其迁移,从而保持原始PSC不变。此备份代码似乎可以在不中断实时堆栈的情况下工作。不过,我有点不确定是否要在2个PSC中添加一个商店

    - (void)backupStore {//saves the store to backup.sqlite
    
        NSFileManager *fm = [[NSFileManager alloc] init];
        NSError *localError = nil;
        _ubiquityURL = [fm URLForUbiquityContainerIdentifier:nil];
        NSURL *backupStoreURL = [NSURL fileURLWithPath:[[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"backupStore.sqlite"]];
        NSURL *iCloudStoreURL = [self iCloudStoreURL];
        NSMutableDictionary *options = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                    [NSNumber numberWithBool:YES],     NSMigratePersistentStoresAutomaticallyOption,
                                    [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
                                    nil];
       [options setObject:@"Logbook" forKey:NSPersistentStoreUbiquitousContentNameKey];
     //Add the store to tempPSC
       NSPersistentStoreCoordinator *tempPSC = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[NSManagedObjectModel mergedModelFromBundles:nil]];
        NSPersistentStore *store = [tempPSC addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:iCloudStoreURL options:options error:&localError];
       //migrate the store to local database
        options = [NSMutableDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],   NSPersistentStoreRemoveUbiquitousMetadataOption,nil];
        if ([tempPSC migratePersistentStore:store toURL:backupStoreURL options:options withType:NSSQLiteStoreType error:&localError]) {
            NSLog(@"migratePersistentStore did it!!");
        } else {
            NSLog(@"migratePersistentStore failed!!...%@",localError);
        }
    
    }
    

    在创建备份存储时,请注意,有报告称migratePersistentStore将取消所有多对多关系,而不会出现任何错误或指示正在这样做。我使用migratePersistentStore在我的应用程序中有一个备份功能(有一个类似的功能用于通过Bonjour共享),并开始获取一些丢失数据的用户报告。虽然上述解决方案可行,但您可能正在悄悄地丢失数据。或者,如果你的计划中没有任何多对多的关系,你很可能会没事。对于“备份”功能的感觉不是很好,对吗

    我为此挣扎了好几天,直到我找到了伊万·巴甫洛夫的帖子,他在那里提交了18480943雷达


    总而言之,如果您的模式具有多对多关系,我不会使用migratePersistentStore,除非您在迁移后也返回并手动重新创建这些关系中的所有链接。

    谢谢,我可以这样做。关于苹果内置的“重新定位”方法,我的编辑有什么想法吗?谢谢你的方法。我已经
    - (void)backupStore {//saves the store to backup.sqlite
    
        NSFileManager *fm = [[NSFileManager alloc] init];
        NSError *localError = nil;
        _ubiquityURL = [fm URLForUbiquityContainerIdentifier:nil];
        NSURL *backupStoreURL = [NSURL fileURLWithPath:[[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"backupStore.sqlite"]];
        NSURL *iCloudStoreURL = [self iCloudStoreURL];
        NSMutableDictionary *options = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                                    [NSNumber numberWithBool:YES],     NSMigratePersistentStoresAutomaticallyOption,
                                    [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
                                    nil];
       [options setObject:@"Logbook" forKey:NSPersistentStoreUbiquitousContentNameKey];
     //Add the store to tempPSC
       NSPersistentStoreCoordinator *tempPSC = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[NSManagedObjectModel mergedModelFromBundles:nil]];
        NSPersistentStore *store = [tempPSC addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:iCloudStoreURL options:options error:&localError];
       //migrate the store to local database
        options = [NSMutableDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],   NSPersistentStoreRemoveUbiquitousMetadataOption,nil];
        if ([tempPSC migratePersistentStore:store toURL:backupStoreURL options:options withType:NSSQLiteStoreType error:&localError]) {
            NSLog(@"migratePersistentStore did it!!");
        } else {
            NSLog(@"migratePersistentStore failed!!...%@",localError);
        }
    
    }