I am working on my first "iCloud App". I worked through the Apple docs and the Stanford videos but I am still struggling to understand the "Big picture" of iCloud.
My goal is to create a "Library style" app (which is Apples term for an app with "a single Core Data stack with a single persistent store coordinator and a single persistent store") like the Employees example.
Following the Stanford videos I am using a UIMangedDocument to setup all Core Data stuff and enable the iCloud capabilities. The UIMangedDocument contains the Database and is "stored in the cloud".
This is already the first thing I struggle with: What does "stored in the cloud" really mean?
Before I started to work with iCloud I thought that to "store a document in the cloud" would mean to "store a copy of the document in the cloud". I thought there would be local version of my document within the regular sandbox and a copy of the document in the cloud. When ever the local document is changed these changes are also transfered to the cloud version. As I understand now this is not correct (at least not completely correct). Am I right?
The first thing I have to do to use iCloud is to call URLForUbiquityContainerIdentifier:. This will return the "iCloud URL" which means the URL of the folder in the cloud. All files which are stored under this URL will be "stored in the cloud", right?
My first assumption (local file + copy in the cloud) is not completely wrong. In fact there is a "local version" and a "cloud version" of any file that is stored in the cloud. This is because I can access the iCloud URL and store files at this location even if the device has currently no Internet connection. But this is only behind the magic of the iCloud framework and nothing I have to bother with. From my point of view the cloud is simple a special folder and any file or directory in this folder is stored in the cloud. The iCloud URL will ony be NIL if iCloud is deactivated in device setting. Is that right?
The second thing I struggle with is how iCloud will sync changes to a Document. Assume "TheApp" on device A creates a UIManagedDocument and stores in in the Cloud. After that device A goes offline. Meanwhile the document is accessed by TheApp on device B and some data is added (e.g. some new employees or departments are inserted). When device B goes online again it will receive the NSPersistentStoreDidImportUbiquitousContentChangesNotification and can merge all call mergeChangesFromContextDidSaveNotification: on the managedObjectContext of the document to copy these changes.
I was not able to find out if merging the changes is really necessary. As described above about from my point of view there is only one Document. If that is true, it is great that I am notified about changes but it should not be necessary to copy these changes to the "local version" of the document because there is not such thing as a "local version". This brings me to the question what mergeChangesFromContextDidSaveNotification: is good for.
Another scenario would be the same situation as before (document created on device A, changed on device B...) but now device A was not just offline but TheApp was completly shutdown while the changes were made on device B. In that case TheApp on device A will have to re-create/re-open the document after it is lauched again. What should happen in this case?
I did run some tests but the result was not always the same. In some cases the document started with its "old" version and than received the notification with the changes. In other cases the document started directly in its new version with all changes on board. For my app the first case (start with old version, receive update notification) would be better, but I was not able force the one or the other behavior. Is this the was it is supposed to work?
Thank you very much!
Generally I can recommend to read the iCloud Design Guide - in particular the section "Designing for Documents in iCloud".
As for your questions:
What does "stored in the cloud" really mean?
If your are using UIManagedDocument following the Stanford videos, your App will upload change logs when data is added/edited/deleted. However your device has kind of a "iCloud Cache" where it stores the iCloud data and access it from (you have access to that folder when you are offline or even when your app is deleted and reinstalled). If you
NSLog
the URLs of the documents in your iCloud folder (you should do this withNSMetadataQuery
you get the path of the iCloud files locally on your device, which is/private/var/mobile/Library/Mobile Documents/<Developer identifier>/<App identifier>/...
For this reason, you'll need to think about a bunch of things when accessing your UI(Managed)Documents on iCloud on the first time app launch or on each app launch (e.g. is iCloud available, do you have network connection, ...).
However, following the way of the videos you'll not have separate documents in your app sandbox and in iCloud (you could achieve this of course when saving your document for creation to the iCloud URL as well as to a local URL in the app sandbox).
The need of merging changes
As described above, your devices are saving change logs which include the adds/edits/deletes to your document. These change logs are uploaded to iCloud and downloaded by the other devices connected to the same iCloud account. Each device can rebuild the current state of your data model with the change logs. This makes iCloud extremly efficient (a complete upload on each time would take much longer). Concerning the sync process of these changes I can also refer to the iCloud Design Guide. In short, you'll have to think about your device syncing the local iCloud folder each time when it comes back to online mode.
For anyone still struggling try this site.
http://ossh.com.au/design-and-technology/software-development/
There are sample apps for iOS and OSX that include iCloud integration, backups, iCloud sync status, etc.
来源:https://stackoverflow.com/questions/9885699/uimanageddocument-icloud-big-picture