iCloud Core Data iOS 6 到 iOS 7 最初是空的本地后备存储

Posted

技术标签:

【中文标题】iCloud Core Data iOS 6 到 iOS 7 最初是空的本地后备存储【英文标题】:iCloud Core Data iOS 6 to iOS 7 empty local fallback store initially 【发布时间】:2013-12-06 09:44:10 【问题描述】:

我正在努力寻找正确或任何好的参考资料来解决我从 ios 6 过渡到 iOS 7 的问题。

我们的 iOS 6 应用程序版本:利用 iCloud,当 iCloud 被禁用/不可用时具有本地备用存储。此 iOS 6 版本已被使用,并且 iCloud 存储文件中填充了相当大量的数据。

我们的 iOS 7 应用版本:配置了新的 iOS 7 iCloud Core Data API。第一次运行此版本时,iOS 6 版本没有捕获任何现有 iCloud 商店的数据,即使该文件存在并包含所有数据。原因是正在使用新的闪亮核心数据后备存储并且不包含任何现有数据。只有在很长的时间延迟后,数据才会出现。这并不理想,因为它看起来好像用户丢失了他们的数据。

是否有针对此问题的现有解决方案,或者是否应该在新的后备存储为空且正在填充时通过使用不同的后备存储来手动处理?

就像脚注一样,模型也有一些轻量级的变化。不确定这个空数据库是否是迁移的产物?将做一个测试,看看我是否可以确定这一点。

【问题讨论】:

【参考方案1】:

最初由 iOS7 下 Core Data 提供的后备存储将不会填充来自 iCloud 的任何数据。但是,如果用户在 iCloud 存储准备就绪之前输入了一些数据,那么这些数据将在可用时迁移到 iCloud 存储。

如果您的应用正在执行轻量级迁移,那么这很可能是您看到延迟的原因。迁移完成并重新启动应用后,启动时间应该会再次变得非常短。

测试延迟是否来自迁移的另一种方法是使用旧模型,因此不需要迁移,并查看这是否会产生重大影响。

请注意,除非您的用户输入数据,否则不会填充新的后备存储。

如果您观察到NSPersistentStoreCoordinatorStoresDidChangeNotificationNSPersistentStoreCoordinatorStoresWillChangeNotification,您将在商店切换时收到通知。

您可能还希望在升级过程中向用户显示一条消息 - 即直到您收到 NSPersistentStoreCoordinatorStoresDidChangeNotification 通知。

观看 WWDC2013 207 会议记录和视频。

编辑: 这是打开 iCloud 文件的日志。这一行

2013-12-11 10:47:10.794 iProject2iOS[5431:60b] AppDelegate.fileOpened called

从 UIManagedDocument 打开完成处理程序调用。这告诉我 UIManagedDocument 已成功打开。此时我知道它正在使用本地后备存储。 在那之后,我必须等待一段时间,才能出现下一行

2013-12-11 10:47:11.291 iProject2iOS[5431:60b] AppDelegate.storesDidChange called - >>>>>>>>>>>>>>>>>>>>>>>>>>>>

这正在处理 storesDidChange 通知,现在我知道该应用正在使用 iCloud 商店。但是,根据设备的不同,如果设备尚未下载和导入任何日志,iCloud 存储也可能仍然是空的。为了解决这个问题,我检查了是否可以在数据库中找到特定的记录,一旦找到它们,我就知道数据导入至少已经进行到加载种子数据。我还应该提到,我在创建本地副本之前检查是否存在 iCloud 文件以避免合并问题。显然,如果 iCloud 关闭,那么这是不可能的。

2013-12-11 10:47:10.290 iProject2iOS[5431:60b] AppDelegate.loadFile called.
2013-12-11 10:47:10.292 iProject2iOS[5431:60b] AppDelegate.managedObjectModel called.
2013-12-11 10:47:10.509 iProject2iOS[5431:60b] AppDelegate. setting merge policy
2013-12-11 10:47:10.545 iProject2iOS[5431:60b] AppDelegate.storesDidChange called - >>>>>>>>>>>>>>>>>>>>>>>>>>>>
2013-12-11 10:47:10.555 iProject2iOS[5431:5877] CoreData: warning: no NSValueTransformer with class name 'NSKeyedUnarchiveFromDataTransformerName' was found for attribute 'preferences' on entity 'Details'
2013-12-11 10:47:10.556 iProject2iOS[5431:5877] CoreData: warning: no NSValueTransformer with class name 'NSKeyedUnarchiveFromDataTransformerName' was found for attribute 'scope' on entity 'Details'
2013-12-11 10:47:10.558 iProject2iOS[5431:5877] CoreData: warning: no NSValueTransformer with class name 'NSKeyedUnarchiveFromDataTransformerName' was found for attribute 'details' on entity 'ExpenseTransaction'
2013-12-11 10:47:10.560 iProject2iOS[5431:5877] CoreData: warning: no NSValueTransformer with class name 'NSKeyedUnarchiveFromDataTransformerName' was found for attribute 'details' on entity 'Interface'
2013-12-11 10:47:10.562 iProject2iOS[5431:5877] CoreData: warning: no NSValueTransformer with class name 'NSKeyedUnarchiveFromDataTransformerName' was found for attribute 'details' on entity 'Issues'
2013-12-11 10:47:10.564 iProject2iOS[5431:5877] CoreData: warning: no NSValueTransformer with class name 'NSKeyedUnarchiveFromDataTransformerName' was found for attribute 'details' on entity 'OpexTransaction'
2013-12-11 10:47:10.568 iProject2iOS[5431:5877] CoreData: warning: no NSValueTransformer with class name 'NSKeyedUnarchiveFromDataTransformerName' was found for attribute 'details' on entity 'ProjectNode'
2013-12-11 10:47:10.570 iProject2iOS[5431:5877] CoreData: warning: no NSValueTransformer with class name 'NSKeyedUnarchiveFromDataTransformerName' was found for attribute 'details' on entity 'Risks'
2013-12-11 10:47:10.573 iProject2iOS[5431:5877] CoreData: warning: no NSValueTransformer with class name 'NSKeyedUnarchiveFromDataTransformerName' was found for attribute 'comments' on entity 'System'
2013-12-11 10:47:10.574 iProject2iOS[5431:5877] CoreData: warning: no NSValueTransformer with class name 'NSKeyedUnarchiveFromDataTransformerName' was found for attribute 'functions' on entity 'System'
2013-12-11 10:47:10.578 iProject2iOS[5431:5877] CoreData: warning: no NSValueTransformer with class name 'NSKeyedUnarchiveFromDataTransformerName' was found for attribute 'details' on entity 'Timesheet'
2013-12-11 10:47:10.608 iProject2iOS[5431:60b] AppDelegate.storesDidChange called - >>>>>>>>>>>>>>>>>>>>>>>>>>>>
2013-12-11 10:47:10.609 iProject2iOS[5431:5877] -[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](754): CoreData: Ubiquity:  mobile~A3BF465A-15C7-46F2-8C68-AC8F49FD15AB:New Project Local_UUID_4D7AFA0C-3C62-452E-8302-6401ED356478
Using local storage: 1
2013-12-11 10:47:10.794 iProject2iOS[5431:60b] AppDelegate.fileOpened called
2013-12-11 10:47:11.291 iProject2iOS[5431:60b] AppDelegate.storesDidChange called - >>>>>>>>>>>>>>>>>>>>>>>>>>>>
2013-12-11 10:47:11.292 iProject2iOS[5431:60b] OpeningViewController.refreshUI: called
2013-12-11 10:47:11.293 iProject2iOS[5431:60b] MenuViewController.refreshUI: called
2013-12-11 10:47:11.294 iProject2iOS[5431:60b] OpeningViewController. about to call displayItem
2013-12-11 10:47:11.295 iProject2iOS[5431:60b] OpeningViewController. displayItem has been called
2013-12-11 10:47:11.649 iProject2iOS[5431:60af] -[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](754): CoreData: Ubiquity:  mobile~A3BF465A-15C7-46F2-8C68-AC8F49FD15AB:New Project Local_UUID_4D7AFA0C-3C62-452E-8302-6401ED356478
Using local storage: 0

如果它是一个正在打开的本地商店,那么这就是调用顺序。因为 iCloud 没有打开,我不希望有另一个 storesDidChange 通知。我在 Open 完成处理程序中设置了一个标志,然后当我收到一个 storesDidChange 通知时,如果设置了这个标志,我会刷新 UI,否则我会忽略它(如果 iCloud 为 ON)。如果我们不使用 iCloud,我不需要调用 refreshUI,因为 UI 由 Open 完成处理程序激活,此时本地存储可用。

2013-12-11 10:55:26.255 iProject2iOS[5440:60b] AppDelegate.application:didFinishLaunchingWithOptions: called
2013-12-11 10:55:26.259 iProject2iOS[5440:60b] AppDelegate.checkUserICloudPreferenceAndSetupIfNecessary called
2013-12-11 10:55:26.460 iProject2iOS[5440:60b] AppDelegate. User preference for au.com.ossh.iProject2.UseICloudStorage is NO
2013-12-11 10:55:26.462 iProject2iOS[5440:60b] AppDelegate. User disabled iCloud
2013-12-11 10:55:26.464 iProject2iOS[5440:60b] AppDelegate. iCloud is active
2013-12-11 10:55:29.977 iProject2iOS[5440:60b] AppDelegate.loadFile called.
2013-12-11 10:55:29.980 iProject2iOS[5440:60b] AppDelegate.managedObjectModel called.
2013-12-11 10:55:30.190 iProject2iOS[5440:60b] AppDelegate. setting merge policy
2013-12-11 10:55:30.231 iProject2iOS[5440:60b] AppDelegate.storesDidChange called - >>>>>>>>>>>>>>>>>>>>>>>>>>>>
2013-12-11 10:55:30.330 iProject2iOS[5440:60b] AppDelegate.fileOpened called

这里是enabling the UI when using Core Data and iCloud 上一些其他详细信息的链接。

【讨论】:

感谢您的回复。那个视频我看了大概20遍。应用程序设置非常复杂,导致 NSPersistentStoreCoordinatorStoresDidChangeNotification 被多次调用。它不仅限于本地/iCloud 存储切换。此外,通知仅包含发生的切换类型和 url。我可能错了,但在切换到 iCloud 商店后,商店的网址似乎保持不变。您知道用于确定是否正在使用本地存储的任何 api 吗?需要此信息才能知道何时应显示消息。 @Schoob 不确定上面的日志是否有帮助,但一旦调用 UIManagedDocument 打开完成处理程序,本地存储就可用。随后的 storesDidChange 是到 iCloud 存储的切换。我想如果你自己在做各种各样的其他商店转换,可能很难弄清楚发生了什么。 顺便说一句,我不确定上述是否始终是 Core Data 的工作方式,但自从我开始使用 iOS7 以来,它似乎一直是一致的。 感谢您的反馈。欣赏它

以上是关于iCloud Core Data iOS 6 到 iOS 7 最初是空的本地后备存储的主要内容,如果未能解决你的问题,请参考以下文章

iOS Core Data iCloud 同步 - 可选

在 iOS 7 中禁用 Core Data 中的 iCloud(也就是将持久存储文件迁移到本地)

iOS 7 iCloud 和(启用/禁用)Core Data - 永无止境的故事

iOS 7 中的 iCloud、Core Data 和来自 Web 服务的数据

Core Data iCloud 获取有时不会产生数据(iOS)

使用 iCloud 在多台设备上同步 Core Data