iCloud basics and code sample [closed]
Solution 1:
I just re-read the docs and it appears that my general approach is wrong. I should first create the file in the sandbox and then move it to the cloud. In other words, Apple seems to suggest that I should have three versions of the same file at all times: one in the directory of my app, one in the iCloud demon directory of my device (which is also accessible if offline) and one in the cloud:
Apps use the same technologies to manage files and directories in iCloud that they do for local files and directories. Files and directories in iCloud are still just files and directories. You can open them, create them, move them, copy them, read and write from them, delete them, or any of the other operations you might want to do. The only differences between local files and directories and iCloud files and directories is the URL you use to access them. Instead of URLs being relative to your app’s sandbox, URLs for iCloud files and directories are relative to the corresponding iCloud container directory.
To move a file or directory to iCloud:
Create the file or directory locally in your app sandbox. While in use, the file or directory must be managed by a file presenter, such as a UIDocument object.
Use the URLForUbiquityContainerIdentifier: method to retrieve a URL for the iCloud container directory in which you want to store the item. Use the container directory URL to build a new URL that specifies the item’s location in iCloud. Call the setUbiquitous:itemAtURL:destinationURL:error: method of NSFileManager to move the item to iCloud. Never call this method from your app’s main thread; doing so could block your main thread for an extended period of time or cause a deadlock with one of your app’s own file presenters. When you move a file or directory to iCloud, the system copies that item out of your app sandbox and into a private local directory so that it can be monitored by the iCloud daemon. Even though the file is no longer in your sandbox, your app still has full access to it. Although a copy of the file remains local to the current device, the file is also sent to iCloud so that it can be distributed to other devices. The iCloud daemon handles all of the work of making sure that the local copies are the same. So from the perspective of your app, the file just is in iCloud.
All changes you make to a file or directory in iCloud must be made using a file coordinator object. These changes include moving, deleting, copying, or renaming the item. The file coordinator ensures that the iCloud daemon does not change the file or directory at the same time and ensures that other interested parties are notified of the changes you make.
However, if you dig a little deeper into the docs concerning setUbiquitous, you'll find:
Use this method to move a file from its current location to iCloud. For files located in an application’s sandbox, this involves physically removing the file from the sandbox directory. (The system extends your application’s sandbox privileges to give it access to files it moves to iCloud.) You can also use this method to move files out of iCloud and back into a local directory.
So this appears to mean that a file / directory gets deleted form the local sandbox and moved into the cloud.
Solution 2:
I've been using your example and I like it for helping me grasp the basics of iCloud. Now I'm wrangling with your question for my own app which has to support existing users of the app with locally stored content who may or may not be using iCloud creating these cases as far as I can tell:
Cases:
- New user
- has icloud - create documents in icloud
- no icloud - create documents locally
- Existing user
- has icloud
- just added - migrate local docs to icloud
- not just added - open/save docs to icloud
- no icloud
- just removed - migrate former icloud docs to local
- not just removed - open/save docs to local
- has icloud
If someone removes iCloud - wouldn't the calls to ubiquitous URL return nil? If that's the case how do I migrate the docs back to local storage? I'll create a user pref for now but seems a bit of a workaround.
I feel like I'm missing something obvious here so if anyone can see it, please chime in.
Solution 3:
If you want users to be able to share text between devices that are pre-iOS 5.0, you are going to have to do what everyone had to do before iCloud and move information to your own server.
All you really need is a server somewhere that lets your app save its text files and associate them with a user account.
You'll need users to create an account and you'll need to manage the process yourself, of moving new information on one device into your own 'cloud'.
Users will register with the same account on other devices and you'll need to take care of detecting when another device has moved data onto your own cloud, and update the current device with the new info.
Obviously, for iOS 5.0 devices, you'll probably want to detect changed files for pre-iOS 5.0 devices in your own cloud, and also be able to talk to iCloud.