iCloud中的数据快照启用了Core Data应用程序?

时间:2013-12-26 09:46:47

标签: core-data icloud snapshot

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

我不是在谈论撤消一个或两个单一更改,而是关于真实快照,时间戳和以保存方式存储。

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

我正在考虑以下情况:

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


    修改

    我成功地使用上述步骤创建了商店的副本。商店的娱乐似乎也在第一次尝试中起作用。但是,我仍然担心我加载商店文件的方式(拉掉旧文件,然后用我保存的文件替换它)。

    但是,我遇到了苹果“另存为... ”或“重新定位”方法

    NSDictionary *options = @{
        NSPersistentStoreRemoveUbiquitousMetadataOption: @YES
    };
    NSPersistentStore *copy = [psc migratePersistentStore:currentiCloudStore
                                                    toURL:url
                                                  options:options
                                                 withType:NSSQLiteStoreType
                                                    error:&error];
    

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

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

4 个答案:

答案 0 :(得分:1)

你的基本方法对我来说很好。我也在使用iCloudCoreDataStack,我认为这是一个强大的解决方案。

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

话虽如此,如果您已经在对象图中进行迭代,那么您可以使用它来做一些额外的事情,这可能会变得有用。您可以将整个对象图转换为JSON并将其存储为文本文件(如果没有可转换或二进制属性)。您的数据现在是人类可读的,并且可以通过更多方式和更多平台使用。

答案 1 :(得分:1)

我一直在寻找一种允许我的用户执行备份快照的解决方案。我无法使用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);
    }

}

答案 2 :(得分:1)

在创建备份存储区时,请注意有些报告表明migratePersistentStore将核对所有多对多关系,而没有任何错误或指示它正在这样做。我在我的应用程序中有一个备份功能(使用与Bonjour共享的类似功能)使用migratePersistentStore并开始获取一些缺少数据的用户报告。虽然上述解决方案可行,但您可能会默默地丢失数据。或者,如果您的计划中没有任何多对多的关系,那么您希望没问题。对于“备份”功能感觉不是很好,对吗?

我一直在努力奋斗,直到我在https://devforums.apple.com/message/1055235#1055235找到Ivan Pavlov的帖子,在那里他提交了雷达18480943。

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

答案 3 :(得分:0)

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

http://ossh.com.au/design-and-technology/software-development/uimanageddocument-icloud-integration/