ios - 开启/关闭iCloud时迁移数据

标签 ios macos core-data icloud core-data-migration

本地帐户

从关于核心数据和iCloud的WWDC 2013 207 session中:

You provide us a single store URL inside the application's local sandbox and we then create an opaque container with an entry inside of it for each account on the system, including the local account, which is our term for what happens when there is no iCloud account on the system. This is a special store that's managed by Core Data so that you don't have to do anything special because your user doesn't have an iCloud account.



在iOS 7/OS X 10.9中,带有iCloud的Core Data将在关闭iCloud的情况下自动使用本地帐户。与后备存储(在iCloud启用但无法访问时使用)不同,当服务开启时,本地帐户将完全由iCloud帐户替换,而不会进行任何合并。仅当iCloud关闭时,本地帐户中的数据才可访问。在以下情况下会发生这种情况:
  • 没有iCloud帐户。
  • 有一个iCloud帐户,但是“文档和数据”已被禁用。
  • 有一个iCloud帐户,但该应用程序已在“文档和数据”中禁用。

  • 以上是我从实验中了解的内容。如果我错了,请纠正我。

    数据消失时

    按原样使用,本地帐户用户体验很糟糕。如果您在关闭iCloud的情况下向应用程序添加数据然后再将其打开,则数据将“消失”,并且您可能会认为它已被删除。如果您在启用iCloud的情况下向应用程序添加数据,然后将其关闭,则数据也会“消失”。

    我已经看到了一些示例,这些示例试图通过在应用程序中添加(更多)iCloud设置并管理自己的“本地”存储(不是iCloud提供的存储)来解决此问题。重复工作给我的感觉到了。

    利用本地帐户进行数据迁移

    这种方法怎么样?
  • 始终使用Core Data和iCloud,无论iCloud处于打开还是关闭状态。
  • 当iCloud从关闭变为开启时,询问用户是否要将本地帐户与iCloud帐户合并。如果是,请合并,删除优先于本地的重复项并清空本地帐户。
  • 当iCloud从打开变为关闭时,询问用户是否要将iCloud存储与本地帐户合并。如果是,请合并并删除优先于iCloud的重复项。

  • 这类似于“提醒”所做的事情。但是,提醒会直接从iCloud设置询问用户有关数据迁移的信息,这是我们开发人员无法做到的。

    问题

    1)这种方法是否具有乍看之下并不明显的任何缺陷或边界情况?也许我们不是要像这样使用iCloud生成的本地帐户。

    2)NSPersistentStoreCoordinatorStoresWillChangeNotificationNSPersistentStoreCoordinatorStoresDidChangeNotification是否足以检测所有可能的iCloud转换?

    3)您会在NSPersistentStoreCoordinatorStoresWillChangeNotificationNSPersistentStoreCoordinatorStoresDidChangeNotification之间进行用户提示和合并,还是收集其中的所有信息并等到商店更改为止?我问是因为这些通知似乎是在后台发送的,阻止它们执行可能较长的操作可能不是Core Data期望的。

    最佳答案

    我认为您误解了207届 session 上的讲话。

    Core Data不会自动为您创建本地存储和iCloud存储,也不会自动关闭iCloud帐户时会同步数据的存储。根据用户选择的内容,您必须使用NSPersistentStoreUbiquityNameKey选项(对于iCloud存储)还是不使用(对于本地存储)来创建存储。

    因为在初次安装应用程序时,新应用程序“数据和文档”的默认安全设置为“开”,所以您必须询问用户是否要使用iCloud。尝试使用Apple的Pages应用程序。

    如果用户随后更改了首选项设置,则您的应用必须将商店迁移到iCloud或从iCloud迁移。

    Core Data自动处理的部分是,如果您切换iCloud帐户(注销并使用其他帐户登录),则该应用程序将以登录该帐户时可能创建的Core Data存储运行。

    请参阅下面的文字记录,其中清楚地说明该帐户消失后,iCloud存储将被删除。没了,卡普特,一只死了的鹦鹉。因此,尽管您有机会仅将更改日志保存在本地,以防将来再次使用该帐户。

    You simply implement your will change handlers and respond to NSPersistentStoreCoordinator Stores Will Change and will notify you automatically when we need to change the persistent store file because there's new account on the system.

    Of course, you can then call NSManagedObjectContext save and NSManagedObjectContext reset.

    Now once you've done that, we'll remove the store from the coordinator just as with the asynchronous setup process and then we'll send you NSPersistentStoreCoordinator Storage Did Change notification, again, just like asynchronous setup and you can begin working with your application as you normally would.

    Now, let's talk about this in a little bit more detail.

    When you receive NSPersistentStoreCoordinator Stores Will Change notification, the persistent store is still available to use, and so unlike what we advised you of last year where you had to immediately drop the persistent store and wipe out your managed object context, you can still write to the managed object context and those changes will be persistent locally to be imported to the account if it every comes back.

    This means that although your user's changes won't make it to iCloud immediately, if they ever sign in again, they'll be there and waiting.

    Finally, all of these store files will be managed by Core Data and that means that we could remove them at any time.

    Each store will be removed once its account has gone away because we can rebuild the file from the cloud.

    So we want to free up as much disk space as possible for your application to use and not have old store files lying around that could take up additional resources.



    并进一步

    We're also introducing a new option to help you create backups or local copies of the iCloud persistent store called NSPersistentStore Remove Ubiquitous Metadata Option.

    This removes all associated metadata from the iCloud store; that means, anything that we write into the metadata dictionary as well as the store file itself, and it's critical if you want to use the migration API to create backups or local copies at a persistent store you wish to open without the iCloud options.



    还可以查看蒂姆·罗德利(Tim Roadley)的书与勘误的链接

    http://timroadley.com/2014/02/13/learning-core-data-for-ios-errata/

    如果您登录到iCloud,然后用户更改了应用程序首选项设置(与“数据和文档”安全性设置不同)以关闭iCloud,则应询问用户是否要将现有的iCloud存储区迁移到本地(再次-使用Pages尝试一下,看看收到什么消息。

    我已经发布了一个示例应用程序,可在此处完成所有这些操作。观看视频以查看预期的行为。
    http://ossh.com.au/design-and-technology/software-development/

    示例应用程序的一些功能包括:

    功能包括:

  • 示例 iOS OSX 与iCloud集成的核心数据应用程序
  • 的使用本地 iCloud 核心数据存储
  • 包括一个设置包(请注意,这会在“设置”应用中创建一个设置页面),其中包括:

  • 使用iCloud首选项设置(打开或关闭)
  • 进行备份首选项设置(ON或OFF)
  • 显示应用程序的版本和内部版本号

  • 当“使用iCloud”首选项更改为“开”时,提示用户有关存储选项的信息。
  • 取决于用户首选项设置和对提示
  • 的响应,将核心数据存储与iCloud 进行迁移。
  • 检测从其他设备删除iCloud存储库,并通过创建新的空iCloud存储库
  • 进行清理
  • 本地存储迁移到iCloud时检查现有的iCloud文件,如果iCloud文件存在
  • ,则提示用户是否合并或丢弃本地存储中的数据
  • 如果“将备份”首选项设置为“开”,则为核心数据存储创建备份。备份文件名是persistentStore_Backup_yyyy_MM_dd_HH_mm_ss。要使用它:

  • 将备份首选项设置为ON,下次激活该应用时,它将对当前Core Data存储进行备份,并将首选项重置为OFF
  • 可以从iTunes将
  • 文件复制到PC或Mac上
  • 还原
  • 只需将应用程序设置为使用本地文件(使用iCloud首选项设置为OFF),然后用所需的备份文件替换persistantStore文件(请注意,该文件必须称为persistentStore)。

  • 编辑记录并在详细 View 中保存/取消对的编辑
  • 核心数据存储的异步打开,以确保长时间的迁移不会阻塞主线程并导致App终止
  • 在主UITableView中通过拉至刷新在后台线程上加载数据以启动另一个后台线程(您可以启动同时运行的多个后台线程,请注意!)
  • 使用UITableView,fetchedResultsController和谓词过滤详细选择
  • 来详细显示相关对象
  • 如果没有存储已经存在,则加载种子数据,检查iCloud文件是否已由其他设备创建
  • iCloud上载/下载状态指示器,当核心数据事务日志需要同步,忙于同步,正在导入或后台任务正在运行时,网络 Activity 指示器点亮
  • 侧边栏样式UI ,具有针对iOS和OS X应用程序的多个主 View 和详细 View
  • 备份文件管理器,它使您可以进行备份,在iCloud之间复制备份文件,从iCloud复制备份文件,通过电子邮件发送和接收备份文件以及从备份文件还原。
  • 关于ios - 开启/关闭iCloud时迁移数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21895343/

    相关文章:

    ios - 访问 swift 中该函数外部的 override func viewDidLoad() { super.viewDidLoad() 函数中创建的变量

    macos - 找不到与命令 "dotnet-ef"匹配的可执行文件 (Csproj)

    macos - 如何从主机上的docker exec的pid检索docker容器名称(MacOS)

    javascript - Mac OSx 使用 sh 将文本插入到创建的文件中

    iphone - 核心数据主键

    objective-c - Today Extension 用于打开商店的模型与用于使用 userInfo 字典创建商店的模型不兼容

    ios - 解包后,CoreDataStack 中的 ManagedObjectContext 返回 nil

    iphone - 在 iOS 应用程序中使用 plist 来保留多步骤表单的数据

    iOS应用程序从现有应用程序升级

    ios - UIAlertView 不在屏幕中央