未启用 iCloud 时,如何存储核心数据日志?



我希望用户能够在禁用iCloud时继续正常使用核心数据存储。我遇到的唯一问题是,他们可能有很多数据在启用时生成日志,然后如果他们再次启用,我要么不添加他们从那时起创建的所有数据,要么添加所有数据,从而复制现有数据。为了避免这个问题,我想在iCloud被禁用时继续记录日志,这样它就可以在再次启用时上传这些更改。

这是我连接到iCloud:时必须执行的代码

NSURL *iCloud = [fileManager URLForUbiquityContainerIdentifier:nil];
NSURL *iCloudLogsPath = [NSURL fileURLWithPath:[[iCloud path] stringByAppendingPathComponent:iCloudLogsDirectoryName]];
NSMutableDictionary *options = [NSMutableDictionary dictionary];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption];
[options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption];
[options setObject:iCloudEnabledAppID            forKey:NSPersistentStoreUbiquitousContentNameKey];
[options setObject:iCloudLogsPath                forKey:NSPersistentStoreUbiquitousContentURLKey];
[psc addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:store
options:options
error:nil];

不幸的是,这不是一个选项。当iCloud启用并且您使用NSPersistentStoreUbiquitousContentNameKey时,核心数据事务日志将自动创建。在其他所有情况下,都不会创建任何事务日志。如果没有启用iCloud,您的代码就无法强制创建日志。当尝试使用带有核心数据的iCloud时,这种情况只是许多意想不到的复杂情况之一。

一种可能的方法是:当你发现iCloud已经启用时,将你的整个数据存储迁移到iCloud,不用担心是否已经有任何东西。然后,使用重复检测方法来剔除重复条目。苹果公司在其SharedCoreData示例项目中提供了一个很好的重复检测代码示例,该项目在WWDC 2012第227届会议上介绍,使用iCloud和核心数据

另一种方法是在禁用iCloud时维护您自己的更改日志。使用NSManagedObjectContextDidSaveNotification监视更改,并保留在禁用iCloud时更改的对象列表。如果已重新启用iCloud,则可以重新保存这些对象以为其生成iCloud事务。

然而,对于这两种情况中的任何一种,都有几个相关的并发症需要考虑:

  1. 如果用户在您的应用程序运行时禁用iCloud,您将无法继续使用现有的持久存储协调器,甚至无法继续使用您现有的数据存储。如果你这样做了,你的应用程序将尝试写入事务日志,因为没有地方放而失败,然后崩溃。您需要移动到新的非iCloud数据存储。您可能可以使用migratePersistentStore:toURL:options:withType:error:在一个步骤中完成这项工作,但必须完成。

  2. 与上述内容相关,如果用户重新启用iCloud,则需要迁移回启用了iCloud的数据存储。

  3. 如果你的应用程序启动时没有启用iCloud,那么在设置持久存储协调器时,你真的应该只使用nil作为选项。检查URLForUbiquityContainerIdentifier:返回的值,并相应地继续使用或不使用iCloud。

  4. 根据我的经验,iCloud的核心数据是不稳定的。除其他事项外,请确定检查addPersistentStoreWithType:etc的返回值,因为它可能会因为没有明显原因而失败(即,您做得很好,但iCloud只是不正常)。

祝你好运,你会需要它的。请记住,截至今天,即使是苹果公司也没有在自己的任何应用程序中使用带有核心数据的iCloud。

最新更新