我的应用程序通过iCloud同步和备份其数据(我正在使用iCloudCoreDataStack来实现此目的)。由于我的应用程序处理用户创建的重要数据,我希望通过不时创建快照的功能提供额外的安全网,以后可以恢复。
我不是在谈论撤消一个或两个单一更改,而是关于真实快照,时间戳和以保存方式存储。
由于我正在利用iCloud同步,我不能简单地交换应用程序中使用的sqlite存储。我想我必须删除当前上下文中的每个对象,创建从快照恢复的对象并保存上下文。然后,设备也会将更改推送到iCloud。
我正在考虑以下情况:
有什么想法吗?这是保存吗,是否有任何需要注意的事项(特别是与iCloud一起)?有没有人以类似的方式做到这一点?
修改
我成功地使用上述步骤创建了商店的副本。商店的娱乐似乎也在第一次尝试中起作用。但是,我仍然担心我加载商店文件的方式(拉掉旧文件,然后用我保存的文件替换它)。
但是,我遇到了苹果“另存为... ”或“重新定位”方法
NSDictionary *options = @{
NSPersistentStoreRemoveUbiquitousMetadataOption: @YES
};
NSPersistentStore *copy = [psc migratePersistentStore:currentiCloudStore
toURL:url
options:options
withType:NSSQLiteStoreType
error:&error];
将删除所有iCloud关联的元数据,并从协调器中删除当前存储(我不希望这样)并将新创建的存储添加到PSC(我也不想要)。
最好的方法是什么?我当前的方法还是Apples内置的“另存为... /重新定位”?我的重点在于以后加载快照,无论是否启用了iCloud。
答案 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/