简体   繁体   English

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

[英]How do I store core data logs when iCloud isn't enabled?

I want the user to be able to keep on using the core data store as normal when iCloud is disabled. 我希望用户能够在禁用iCloud时继续正常使用核心数据存储。 The only problem I'm having with that is that they might have a lot of data which produced logs when it was enabled, and then if they enable it again, i'm stuck with either not adding all the data they made since then or adding all data, thus duplicating the existing data. 我遇到的唯一问题是,它们可能有很多数据在启用时生成日志,然后如果它们再次启用它,我会坚持要么不添加自那时以来所做的所有数据,要么添加所有数据,从而复制现有数据。 To avoid this problem, I want to keep making logs when iCloud is disabled, so it can just upload those changes when it is enabled again. 为了避免这个问题,我希望在禁用iCloud时继续制作日志,这样它就可以在再次启用时上传这些更改。

This is the code I have to do it when connected to 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];

Unfortunately this is not an option. 不幸的是,这不是一个选择。 When iCloud is enabled and you use NSPersistentStoreUbiquitousContentNameKey , Core Data transaction logs are created automatically. 启用iCloud 使用NSPersistentStoreUbiquitousContentNameKey ,将自动创建Core Data事务日志。 In every other case, no transaction logs get created. 在所有其他情况下,不会创建任何事务日志。 There is no way for your code to force the logs to be created without having iCloud enabled. 如果没有启用iCloud,您的代码就无法强制创建日志。 This kind of situation is just one of many unexpected complications when attempting to use iCloud with Core Data. 当尝试将iCloud与Core Data一起使用时,这种情况只是许多意想不到的复杂情况之一。

One possible approach: When you discover that iCloud has been enabled, migrate your entire data store to iCloud and don't worry about whether anything is already there. 一种可能的方法:当您发现已启用iCloud时,将整个数据存储迁移到iCloud,并且不必担心是否已存在任何内容。 Then, use a duplicate detection method to weed out duplicate entries. 然后,使用重复检测方法清除重复的条目。 Apple provided a good example of duplicate detection code in their SharedCoreData sample project, covered at WWDC 2012 session 227, Using iCloud with Core Data . Apple在他们的SharedCoreData示例项目中提供了一个很好的重复检测代码示例,在WWDC 2012会话227, 使用iCloud和Core Data进行了介绍

Another approach would be to maintain your own change logs while iCloud is disabled. 另一种方法是在禁用iCloud时维护自己的更改日志。 Use NSManagedObjectContextDidSaveNotification to watch for changes, and keep your own list of objects that changed while iCloud was disabled. 使用NSManagedObjectContextDidSaveNotification监视更改,并保留您自己的iCloud禁用时更改的对象列表。 If iCloud is reenabled, you can then re-save those objects to generate iCloud transactions for them. 如果重新启用iCloud,则可以重新保存这些对象以为它们生成iCloud事务。

With either of those, though, there are a couple of related complications to consider: 但是,无论哪一种,都需要考虑几个相关的复杂情况:

  1. If the user disables iCloud while your app is running, you cannot continue using your existing persistent store coordinator or even your existing data store. 如果用户在您的应用程序运行时禁用iCloud,则无法继续使用现有的持久存储协调程序甚至是现有的数据存储。 If you do, your app will attempt to write transaction logs, fail because there's no place to put them, and then crash. 如果这样做,您的应用程序将尝试编写事务日志,失败,因为没有地方可以放置它们,然后崩溃。 You'll need to move to a new, non-iCloud data store. 您需要转移到新的非iCloud数据存储。 You can probably use migratePersistentStore:toURL:options:withType:error: to do this in one step, but you must do it. 您可以使用migratePersistentStore:toURL:options:withType:error:一步完成此操作,但您必须执行此操作。 (As an aside, it might be possible to just mess with the data store's metadata, but this is undocumented and I don't know what key(s) to wipe out). (顺便说一下,有可能只是弄乱数据存储的元数据,但这没有记录,我不知道要消除哪些键)。

  2. Related to the above, if the user reenables iCloud, you'll need to migrate back to an iCloud-enabled data store. 与上述相关,如果用户重新启用iCloud,您将需要迁移回启用iCloud的数据存储。

  3. If iCloud is not enabled when your app starts up, you should really just use nil for the options when setting up the persistent store coordinator. 如果在您的应用启动时未启用iCloud,则在设置持久性存储协调器时,您应该只使用nil作为选项。 Check the value returned by URLForUbiquityContainerIdentifier: and proceed with or without iCloud accordingly. 检查URLForUbiquityContainerIdentifier:返回的值URLForUbiquityContainerIdentifier:并相应地继续或不使用iCloud。

  4. In my experience-- Core Data with iCloud is flaky . 根据我的经验 - 使用iCloud的核心数据很不稳定 Among other things, be certain to check the return value from addPersistentStoreWithType:etc because it might fail for no readily apparently reason (ie you did everything right but iCloud is just not behaving). 除其他外, 一定要检查addPersistentStoreWithType:etc的返回值,因为它可能会因为没有明显的原因而失败(即你做的一切都正确,但iCloud只是没有表现)。

Good luck, you will need it. 祝你好运,你需要它。 Keep in mind that as of today, even Apple doens't use iCloud with Core Data in any of their own apps. 请记住,截至今天,即使Apple也不会在自己的任何应用程序中使用iCloud和Core Data。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM