Syncing Core Data across multiple devices using iC

2019-03-26 05:42发布

问题:

There has been a lot of discussion lately about the issues with iCloud and Core Data and how Apple's APIs are currently broken in iOS 5 and possibly iOS 6.

Is it possible, given the current state of Apple's Core Data API, to reliably sync across multiple devices using iCloud?

If so, how would you do this? If not, please recommend an alternative approach.

回答1:

It depends on what you want to do. There are two types of Core Data-iCloud integration, as described here: http://developer.apple.com/library/ios/#releasenotes/DataManagement/RN-iCloudCoreData/_index.html

There are broadly speaking two types of Core Data-based application that integrate with iCloud:

Library-style applications, where the application usually has a single persistent store, and data from the store is used throughout the application. Examples of this style of application are Music and Photos.

Document-based applications, where different documents may be opened at different times during the lifetime of the application. Examples of this style of application are Keynote and Numbers.

If you're using the library-type, this article is the first of a series that goes into a lot of the problems that will come up: http://mentalfaculty.tumblr.com/post/23163747823/under-the-sheets-with-icloud-and-core-data-the-basics.

You can also check out sessions 218 (for document-based) or 227 (for library-style) of this year's wwdc.



回答2:

This blog post will lead you to a chain of recent articles about the travails of developers attempting this approach.

From my own understanding and experience, I believe it is doable, but don't buy into the idea that you will get anything "for free". Depending on your data model, you may be better off syncing your whole persistent store as a document rather than using the documented core data / iCloud approach.

You may have better luck if you're already comfortable with Core Data. Just be sure you think through how to handle several important cases.

One is what to do if the user signs out of their iCloud account. When this happens, the local ubiquitous persistent store is deleted. If it makes sense for the user to still have access to their data, you'll need to manage a copy in local storage, and then manage resynchronizing when they sign back in.

Another is that changes can apparently be quite slow to propagate by default, so you may want to consider an alternative mechanism, such as the key value store, to quickly propagate sufficient information to avoid a bad user experience.

Conflict management is perhaps the most challenging (depending on your model). While the framework provides a mechanism to inform you of conflicts, you are on your own for providing a mechanism to resolve them, and there are reports that the conflict notifications may not be reliable (see linked articles), which seems strongly linked to the lag in updating.

In short, if you go into this understanding that the actual support is pretty bare bones and that you'll need to code very defensively, you may have a chance. There aren't any good recipes out there, so if you do make it work, please come back and tell us what works!



回答3:

As of iOS 7, the best solution is probably the Ensembles framework: https://github.com/drewmccormack/ensembles

Additionally, there is a promising project which will essentially allow you to do the same thing using a different cloud service.

Here is a link to the repository: https://github.com/nothirst/TICoreDataSync

Project description:

TICoreDataSync is a collection of classes to enable synchronization via the Cloud (including Dropbox) of Core Data-based applications (including document-based apps) between any number of clients running under Mac OS X or iOS. It's designed to be easy to extend if you need to synchronize via an option that isn't already supported.

Reasons for why iCloud is not currently reliable:

  • "Sometimes, iCloud simply fails to move data from one computer to another."
  • "Corrupted baselines are [a] common obstacle.... There is no recovery from a corrupted baseline, short of digging in to the innards of your local iCloud storage and scraping everything out, and there is no visible indication that corruption has occurred — syncing simply stops."
  • "Sometimes, when initializing the iCloud application subsystem, it will simply return an opaque internal error. When it fails, there’s no option to recover — all you can do is try again (and again…) until it finally works."
  • "[W]hen you turn off the “Documents & Data” syncing option in the iCloud system preferences, the iCloud system deletes all of your locally stored iCloud data[.]"
  • When you sign out of iCloud, the system moves your iCloud data to a location outside of your application’s sandbox container, and the application can no longer use it.
  • "In some circumstances (and we haven’t been able to figure out which, yet), iCloud actually changes the object class of an item when synchronizing it. Loosely described, the object class determines the type of the object in the database[.]"
  • "In some cases (again, not all the time), iCloud may do one of the following:
    • Owner relationships in an item’s data will point to the wrong owner;
    • Owner items get lost in synchronization and never appear on computers other than the one on which they were created. (This leads to the item never appearing in the UI on any other machine.) When this happens, bogus relationships get created between blob items and an arbitrary unrelated owner."
  • "Sometimes (without any apparent consistency or repeatability), the associated data for an object (for example, the PDF data for a PDF item, or the web archive data for a Web Archive item) would simply fail to show up on the destination machine. Sometimes it would arrive later (much later — minutes or hours)."

Quoted and paraphrased from these sources:

  • http://www.imore.com/debug-12-icloud-core-data-sync
  • http://rms2.tumblr.com/post/46505165521/the-gathering-storm-our-travails-with-icloud-sync

Note: I have seen one article where the author mentions getting it to work for iOS 6+, but they don't provide any examples: http://zaal.tumblr.com/post/46718877130/why-you-want-to-use-core-data-icloud-sync-if-only-it


As a reference, here are Apple's docs on iCloud + Core Data:

  • http://developer.apple.com/library/ios/#releasenotes/DataManagement/RN-iCloudCoreData/
  • http://developer.apple.com/library/ios/#documentation/General/Conceptual/iCloudDesignGuide/Chapters/DesignForCoreDataIniCloud.html
  • http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/CoreDataVersioning/vmCloud/vmCloud.html

And here is an example app:

  • http://developer.apple.com/library/ios/#DOCUMENTATION/General/Conceptual/iCloud101/Introduction/Introduction.html


回答4:

The Apple developer tutorial on using the iCloud API to manipulate documents might be a good place to start.

Your Third iOS App introduces you to the iCloud document storage APIs. You use these APIs to store and manipulate files in a user’s iCloud storage.