天天看點

iCloud StorageiCloud Storage

iCloud Storage

iCloud storage is a set of interfaces and services for sharing data among instances of your app running on different devices. The idea behind iCloud is to provide a single place where your app can write its data. Changes made by one instance of your app are propagated to the user’s other devices seamlessly so that the other instances of your app see them too. This creates a more coherent user experience by eliminating the need to synchronize data explicitly between devices or have a computer act as a hub for storing all of the user’s files and data.

There are two ways to adopt iCloud storage in your app:

  • iCloud document storage—Use this feature to store user documents and app data in the user’s iCloud account.
  • iCloud key-value data storage—Use this feature to share small amounts of noncritical configuration data among instances of your app.

Most of the iCloud interfaces are aimed at helping you manage files, not your user interface. Adopting iCloud storage requires some changes to your app’s data model and how it tracks and manages files. Depending on your app, it might also require changes to your app’s user interface and overall configuration. And if you want to share files between iOS and Mac OS X devices, it might require changing how you construct your file formats too.

Important: Access to iCloud is controlled using entitlements, which your app configures through Xcode. If these entitlements are not present, your app is prevented from accessing files and other data in iCloud. For information about how to configure your app’s iCloud entitlements, see “Configuring Your App’s iCloud Entitlements.”

Most applications will use iCloud document storage to share documents from a user’s iCloud account. This is the feature that users think of when they think of iCloud storage. A user cares about whether documents are shared across devices and can see and manage those documents from a given device. In contrast, the iCloud key-value data store is not something a user would see. It is a way for your application to share very small amounts of data (tens of kilobytes) with other instances of itself. Applications can use this feature to store important state information. A magazine application might save the issue and page that the user read last, while a stocks application might store the stock symbols the user is tracking.

The placement of files in your application’s home directory determines what gets backed up and what does not. Anything that would be backed up to a user’s computer is also backed up wirelessly to iCloud. Thus, everything in the 

Documents

 directory and most (but not all) of your application’s 

Library

 directory. To minimize the amount of data stored in the user’s iCloud account, developers are encouraged to put more files in the 

Library/Caches

 directory, especially if those files can be easily re-created or obtained in another way.

Design Considerations for iCloud Apps

When adopting iCloud, the first decision you have to make is whether to use document storage or key-value data storage. Document storage is intended for storing your app’s data, whether that data is created and managed privately by your app or is created by the user and accessible by other means. Document storage is definitely intended for apps that work with user-facing data, such as user-created documents, but it is also useful for managing the data files your app creates internally too. Key-value storage is intended more for noncritical configuration data that you want to share among the running instances of your app. For example, you might use key-value storage to store preferences and other bits of configuration data that are secondary to your app’s behavior. You should avoid using key-value storage to save user-facing data.

iCloud StorageiCloud Storage

Table 4-1 highlights some of the key usage patterns surrounding iCloud storage and how those patterns differ for document storage and key-value storage. Use this table to help answer some of your basic questions.

Table 4-1  Differences between document and key-value storage

Attribute Document storage Key-value storage
What kind of data can it manage? Files and directories Property-list data types only (numbers, strings, dates, and so on)
When would you use it? Use document storage to manage data that is critical to your app. You almost always use document storage to manage files and data related directly to your app’s main data model. Thus, you would use document storage for user documents, private app data files, and any files containing app or user-generated data. Use key-value storage for things like preferences and other configuration data that you want to share between instances of your app but that is not critical to your app’s behavior. The amount of space in the key-value store is limited and the types of data you can store are limited toproperty list data types.
Are file presenters and file coordinators required? Yes No
How do you locate data? Use a 

NSMetadataQuery

 object to search for files.
Use the default 

NSUbiquitousKeyValueStore

 object to retrieve the value for a known key.
How do you manage the data? Manage files and directores using the

NSFileManager

 class. Open, close, read, and write files using standard file system routines.
Set or get keys and values using the default

NSUbiquitousKeyValueStore

 object.
How much data can it store? Limited only by the amount of space in the user’s iCloud account. Limited to a maximum of 64 KB (with a separate per-key limit of 64 KB).
How are conflicts handled? Your app’s file presenters must resolve conflicts manually. The last value set for the key is always the current value. The timestamp provided by the device is used to determine the newest value.
What entitlement is required to use it?

com.apple.developer.ubiquity-container-identifiers

com.apple.developer.ubiquity-kvstore-identifier

When is data synchronized? iCloud always pulls file metadata and data from a device when changes occur. Devices always pull file metadata but usually do not pull changed data until your app attempts to use the file. Keys and values are transferred to and from iCloud at periodic intervals.
How do you detect if iCloud is available at launch time? Call the

URLForUbiquityContainerIdentifier:

method for one of your registered container directories. If the method returns 

nil

, document storage is not available.
Call the 

synchronize

 method of the

NSUbiquitousKeyValueStore

 object. If that method returns 

YES

, iCloud is available and there are changes to synchronize with your local user defaults database. If that method returns 

NO

, iCloud is either not available or there are no changes to synchronize. Either way, use the values in your local user defaults database.
What user interface support is provided? None. Your app is responsible for deciding what information (if any) to convey about iCloud support. In general, iCloud information should be conveyed seamlessly and involve minimal changes to your user interface. None. In most cases, you should not need to convey whether key-value data is stored locally or in iCloud.

Another design consideration is how you plan to incorporate iCloud support into your app’s user interface. Especially for documents, there may be times when you need to inform the user about the state of a document, such as whether it is downloaded or has version conflicts that need to be resolved. In those situations, you should consider adding some unobtrusive elements to your user interface to convey the appropriate information to the user. For more information about updating your user interface, see“Updating Your User Interface for iCloud.”

Configuring Your App’s iCloud Entitlements

Apps that use iCloud must be signed with iCloud-specific entitlements. These entitlements provide a level of security for your app by ensuring that only your apps can access the documents they create. The system also relies on the entitlement values you provide to differentiate your app’s documents from other documents in the user’s iCloud account.

To enable iCloud entitlements for your iOS app in Xcode:

  1. Select your app target in Xcode.
  2. Select the Summary tab.
  3. In the Entitlements section, enable the Enable Entitlements checkbox.

When you enable entitlements for your app target, Xcode automatically configures both the document storage and and key-value data storage entitlements for your app. Each entitlement consists of an entitlement key whose value is one or more container identifier strings. A container identifier string identifies one of the iCloud container directories you use to store your app’s files. Xcode configures the entitlements in the following way:

  • The iCloud Containers field identifies the list of container directories that your app can access in the user’s iCloud storage. (This field corresponds to the 

    com.apple.developer.ubiquity-container-identifiers

     entitlement.) The strings you add to this list must correspond to bundle identifiers for apps created by your team. Xcode uses the current app’s bundle identifier to specify the first string; you can change this to a different bundle identifier if you want multiple apps to share a main container directory. You can also add additional bundle identifiers for your team’s other apps. (The first string must not contain any wildcard characters but subsequent strings may if you do not want to specify every bundle identifier separately.)
  • The iCloud Key-Value Store field contains the single container identifier string corresponding to the iCloud key-value data storage for your app. (This field corresponds to the 

    com.apple.developer.ubiquity-kvstore-identifier

     entitlement.)

The bundle identifiers you specify in Xcode do not represent the fully qualified container identifier strings that are written to your entitlements file. A fully qualified container identifier is of the form <TEAM_ID>

.

<BUNDLE_IDENTIFIER>, where <TEAM_ID> is the unique ten-character identifier associated with your development team and <BUNDLE_IDENTIFIER> is is one of the bundle identifiers in the iCloud Containers field. When retrieving a URL for a container directory in your code, you need to pass the fully qualified string to the

URLForUbiquityContainerIdentifier:

 method. However, you can also pass 

nil

 to this method to retrieve the URL for the first container directory in the list.

Note: You can find the unique <TEAM_ID> value for your development team in the Member Center on the Apple Developer website (http://developer.apple.com/membercenter). From the Member Center home page, select the Your Account tab and then select Organization Profile from the column on the left of that tab. Your team’s identifier is in the Company/Organization ID field.

Apps using iCloud document storage can read and write the contents of multiple container directories by specifying multiple container identifiers in their entitlements file. The iCloud Containers field lets you specify multiple strings. The first string in this field must always be the main container identifier for your app. Any additional strings represent the container identifiers for your other apps. Searches return a merged set of files from all of the available container directories.

For more information about how to configure entitlements for an iOS app, see “Configuring Applications” in iOS App Development Workflow Guide.

Using iCloud Document Storage

iCloud document storage lets you move files and directories to a user’s iCloud account and manage them there. Changes made to the file or directory on one device are stored locally and then pushed to iCloud using a local daemon, as shown in Figure 4-1. The transfer of files to and from each device is transparent to your app. Thus, apps simply operate on the file as if it is always there.

Figure 4-1  Pushing document changes to iCloud

iCloud StorageiCloud Storage

Designing your app to take advantage of iCloud document storage requires some significant changes. Here are the main changes needed:

  • Early in your app’s execution, call the 

    URLForUbiquityContainerIdentifier:

     method to determine if iCloud is enabled. Calling this method is also necessary to extend your app sandbox to include each of your app’s requested container directories; see “Determining if iCloud Document Storage is Available.”
  • Explicitly incorporate file presenters (such as the 

    UIDocument

     class) into your data layer; see “Incorporating File Presenters into Your Workflow.”
  • Explicitly move files to iCloud; see “Manipulating Files and Directories in iCloud.”
  • Be prepared to handle version conflicts for a file; see “Choosing a Strategy to Respond to Version Conflicts.”
  • Make use of searches to locate files in iCloud; see “Incorporating Search into Your Infrastructure.”
  • Be prepared to handle cases where files are in iCloud but not fully downloaded to the local device; this might require providing the user with feedback; see “Determining the Transfer Status of a File or Directory.”
  • Use Core Data if you want to store live databases in iCloud; do not use SQLite.
  • If you also have a Mac OS X version of your app, use a common document format for both apps.

Most of the work you do to support iCloud happens in the data layer of your app. Interactions with iCloud occur mostly through the files and directories that your app uses to store data. But you also need to consider the implications that the underlying data changes have on your app’s user interface. Wherever possible, the user should not have to care whether a file is stored locally or in iCloud. The exceptions are in cases where the user experience might be degraded.

Determining if iCloud Document Storage is Available

Every user with an Apple ID receives a free iCloud account but some users might choose not to enable iCloud for a given device. Before you try to use any other iCloud interfaces, you must call the 

URLForUbiquityContainerIdentifier:

 method to determine if iCloud is enabled. This method returns a valid URL when iCloud is enabled (and the specified container directory is available) or 

nil

 when iCloud is disabled.

The first time you call the 

URLForUbiquityContainerIdentifier:

 method for a given container directory, iOS extends your application sandbox to include that container directory. Thus, it is important that you call this method at least once to ensure that iCloud is enabled and that your main container directory is accessible. And if your application accesses multiple container directories, you should call the method once for each directory.

Incorporating File Presenters into Your Workflow

All files and directories stored in iCloud must be managed by a file presenter object, and all changes you make to those files and directories must occur through a file coordinator object. A file presenter is an object that adopts the 

NSFilePresenter

 protocol. A file presenter’s job is to act as a responsible agent for a given file or directory. Before an external source can change a file, the registered file presenters for that file are notified and given an opportunity to perform any necessary bookkeeping tasks. When your app wants to change a file, it must essentially lock the file by making its changes through an 

NSFileCoordinator

 object. The file coordinator prevents external sources from modifying the file at the same time and delivers relevant notifications to other file presenters.

The simplest way to incorporate file presenters into your app is to use the 

UIDocument

 class. This class implements the methods of the

NSFilePresenter

 protocol and handles all of the file-related management for you. All your app has to do is read and write the document data when told to do so. You can use the 

UIDocument

 class both for files that contain user-generated content (and thus are displayed directly to the user) and for files that your app creates on behalf of the user and manages without user intervention.

For more information about how to incorporate the 

UIDocument

 class into your app’s data structures, see Document-Based Application Programming Guide for iOS. For information on how to create custom file presenters to manage files and directories, see File System Programming Guide.

Manipulating Files and Directories in iCloud

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:

  1. 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.
  2. Use the 

    URLForUbiquityContainerIdentifier:

     method to retrieve a URL for the iCloud container directory in which you want to store the item.
  3. Use the container directory URL to build a new URL that specifies the item’s location in iCloud.
  4. 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.

Note: When naming files and directories, use the alphanumeric character set as much as possible and avoid special punctuation or other special characters. You should also assume that filenames are case insensitive. Keeping your filenames simple helps ensure that those files can be handled correctly on different types of file systems.

For more information about how to manipulate files and directories, see File System Programming Guide.

Choosing a Strategy to Respond to Version Conflicts

Version conflicts for files in iCloud are inevitable, and so your app needs to have a strategy for handling them. Conflicts occur when two instances of an app change a file locally and both changes are then transferred to iCloud. For example, this can happen when the changes are made while the device is in Airplane mode and cannot transmit changes to iCloud right away. When it does happen, iCloud stores both versions of the file and notifies the apps’ file presenters that a conflict has occurred and needs to be resolved.

Apps should always attempt to resolve conflict versions as soon as possible. When a conflict occurs, one file is always designated as thecurrent file and any other versions are marked as conflict versions. Both the current file and any conflict versions are managed by instances of the 

NSFileVersion

 class and can be retrieved using class methods of that class.

To resolve a conflict:

  1. Get the current file version using the 

    currentVersionOfItemAtURL:

     class method.
  2. Get an array of conflict versions using the 

    unresolvedConflictVersionsOfItemAtURL:

     class method.
  3. For each file version object, perform whatever actions are needed to resolve the conflict. For example:
    • Merge the changed data from the conflicting files, if it is practical to do so.
    • Ignore one of the conflicting versions, if you can do so safely or without losing any data.
    • Prompt the user to select which version of the file (current or conflict) to keep. This should always be the last option.
  4. Update the current file as needed:
    • If the current file remains the winner, you do not need to update the current file.
    • If a conflict version is chosen as the winner, use a coordinated write operation to overwrite the contents of the current file with the contents of the conflict version.
    • If the user chooses to save the conflict version under a different name, create the new file with the contents of the conflict version.
  5. Set the 

    resolved

     property of the conflict version objects to 

    YES

    .

    Setting this property to 

    YES

     causes the conflict version objects (and their corresponding files) to be removed from the user’s iCloud storage.

Detecting conflicts depends on whether your app uses 

UIDocument

 or implements custom file presenters. If your app uses the 

UIDocument

class, you detect states by monitoring the value of the 

documentState

 property and observing the related state change notification. If you implement custom file presenters, whenever a new version is reported, you should check to see whether it is a conflict version.

For more information about handling conflicts in 

UIDocument

 objects, see Document-Based Application Programming Guide for iOS. For information about responding to conflicts in custom file presenters, see File System Programming Guide.

Incorporating Search into Your Infrastructure

Unlike files that live in your app’s sandbox, files in iCloud can be added or removed without your app necessarily knowing it. When the user creates a new file on one device, that file eventually appears on the user’s other devices. If the instance of your app running on those other devices is not actively looking for files, there may be a delay in them appearing in your user interface. For this reason, apps should use

NSMetadataQuery

 objects to search for items in iCloud container directories. You can leave a metadata query running in order to receive notifications as files are added or removed. You should leave queries running only while your app is in the foreground and should stop them when your app moves to the background.

Important: Metadata queries return results only when iCloud is enabled and the corresponding container directories have been created. At launch time, use the 

URLForUbiquityContainerIdentifier:

 method to determine if iCloud is enabled and your app’s supported container directories are available. That method also creates the corresponding directory if it does not yet exist.

Metadata queries search all of the container directories listed in your app’s 

com.apple.developer.ubiquity-container-identifiers

entitlement and return a merged set of results. If you want the contents of a single container directory, you can alternatively use the

URLForUbiquityContainerIdentifier:

 method to get the URL for that directory and obtain a static list of its contents using the

NSFileManager

 class.

For information about how to create and configure metadata search queries, see File Metadata Search Programming Guide. For information about how to iterate directories using 

NSFileManager

, see File System Programming Guide.

Determining the Transfer Status of a File or Directory

Items you write to an iCloud container directory are transferred automatically to the iCloud server as quickly as possible. However, depending on the network and the type of device, a file might not be uploaded to the server or downloaded to a device immediately. In cases where you need to know the state of a file, you can use the 

getResourceValue:forKey:error:

 method of 

NSURL

 to retrieve the value for one of the following attributes:

  • NSURLIsUbiquitousItemKey

    —Indicates whether or not the item is stored in iCloud.
  • NSURLUbiquitousItemIsDownloadedKey

    —Indicates whether the current version of the item is downloaded and accessible.
  • NSURLUbiquitousItemIsDownloadingKey

    —Indicates whether the current version of the item is being downloaded and is not yet available.
  • NSURLUbiquitousItemPercentDownloadedKey

    —For an item being downloaded, indicates what percentage of the changes have already been downloaded. You can use this value to update progress bars.
  • NSURLUbiquitousItemIsUploadedKey

    —Indicates that locally made changes were successfully uploaded to the iCloud server.
  • NSURLUbiquitousItemIsUploadingKey

    —Indicates that locally made changes are being uploaded to the iCloud server now.
  • NSURLUbiquitousItemPercentUploadedKey

    —For an item being uploaded, indicates what percentage of the changes have already been uploaded to the server.

Although the iCloud server aggressively pulls changes your app makes locally, iOS devices typically do not pull changes from the server until you try to access the file. If you try to open a file that is currently being downloaded, iOS blocks the thread that issued the open request until the file is downloaded and available for use. Thus, if you are concerned about potential delays, check the file’s current state as needed and possibly update your user interface to reflect that the file is not yet available or is currently downloading.

For more information about the attributes you can request for URLs, see NSURL Class Reference.

Working With Files That Are Not Yet Downloaded

When a change occurs to a file in iCloud, iOS devices do not automatically download the data associated with that change. Instead, iOS devices download the metadata for the file so that they know that a change exists. The actual data for the file is not downloaded until one of the following happens:

  • Your app attempts to open or access the file.
  • Your app calls the 

    startDownloadingUbiquitousItemAtURL:error:

     method to download the changes explicitly.

If your app opens a file that is not yet downloaded, the file coordinator used to open the file blocks your app until the file or its changes have been downloaded. Depending on the size of the changes, this might not lead to the best user experience, so it is preferable to check the download status of a file before trying to open it. The 

NSURL

 class defines properties related to iCloud items, including whether the file is stored in iCloud and whether it is currently downloaded. To obtain the value for one of these keys, use the

getResourceValue:forKey:error:

 method of 

NSURL

. For example, to determine whether a file was downloaded, you could use code similar to the following:

- (BOOL)downloadFileIfNotAvailable:(NSURL*)file {
      
NSNumber*  isIniCloud = nil;
      
if ([file getResourceValue:&isIniCloud forKey:NSURLIsUbiquitousItemKey error:nil]) {
      
// If the item is in iCloud, see if it is downloaded.
      
if ([isIniCloud boolValue]) {
      
NSNumber*  isDownloaded = nil;
      
if ([file getResourceValue:&isDownloaded forKey:NSURLUbiquitousItemIsDownloadedKey error:nil]) {
      
if ([isDownloaded boolValue])
      
return YES;
      
// Download the file.
      
NSFileManager*  fm = [NSFileManager defaultManager];
      
[fm startDownloadingUbiquitousItemAtURL:file error:nil];
      
return NO;
      
}
      
}
      
}
      
// Return YES as long as an explicit download was not started.
      
return YES;
      
}
      

For more information about the iCloud-related properties available for your URLs, see NSURL Class Reference.

Updating Your User Interface for iCloud

Any user interface changes you make related to iCloud should be as unobtrusive as possible to the user. The documents you store in iCloud are the same ones you store locally when iCloud is not available. The only difference is their location in the file system. So the bulk of your user interface should look about the same.

Sometimes, though, you might want to modify your user interface for iCloud. Modify your UI:

  • When a user-generated document must be downloaded before it can be used. Giving the user control over whether to download a document is needed only if your app presents some sort of document browser. For files your app manages privately, download them automatically if they are not available. Any indicators you use should be subtle and provide the user with the option to begin downloading the document. If a download might take more than a few seconds, you might also want to display the current download progress.
  • When there is a version conflict that the user must resolve. Version conflicts can occur when the same document is modified on two different devices at the same time. (This can occur if one of the devices was not connected to the network when the changes were made.) If your app needs user assistance to resolve the conflict, present a subtle indicator that this is the case. Do not display an alert or any sort of disruptive interface to notify the user that a conflict exists.
  • When you want to give the user the option to enable or disable iCloud usage entirely for your app. If your app includes a Settings bundle or inline preferences, you could include a preference to toggle whether your app stores content in iCloud at all. For example, an app whose data consists entirely of privately managed files might do this to give the user the choice of how those files are stored.

For tips and guidance about how to design your app’s user interface, see iOS Human Interface Guidelines.

Using iCloud Key-Value Data Storage

Apps that want to store preferences or small amounts of noncritical configuration data can use the iCloud key-value data store to do so. The key-value data store is similar conceptually to the local user defaults database that you use to store your app’s preferences. The difference is that the keys in the iCloud store are shared by all of the instances of your app running on the user’s other devices. So if one app changes the value of a key, the other apps see that change and can use it to update their configuration.

Important: Apps that use the 

NSUbiquitousKeyValueStore

 class must request the 

com.apple.developer.ubiquity-kvstore-identifier

 entitlement. If you configure multiple apps with the same value for this entitlement, all of them share the same key-value data. For more information about configuring iCloud entitlements, see “Configuring Your App’s iCloud Entitlements.”

To write data to the key-value data store, use the 

NSUbiquitousKeyValueStore

 class. This class is conceptually similar to the

NSUserDefaults

 class in that you use it to save and retrieve simple data types such as numbers, strings, dates, arrays, and so on. The main difference is that the 

NSUbiquitousKeyValueStore

 class writes that data to iCloud instead of to a local file.

The space available in your app’s key-value store is limited to 64 KB. (There is also a per-key limit, which currently is set to 64 KB.) Thus, you can use this storage to record small details but should not use it to store user documents or other large data archives. Instead, store small pieces of data that might improve the user experience for your app. For example, a magazine app might store the current issue and page number that the user is reading. That way, when the user opens the app on another device, that app can open the magazine to the same issue and page that the user was reading.

The 

NSUbiquitousKeyValueStore

 class must not be used as a replacement for the 

NSUserDefaults

 class. An app should always write all of its configuration data to disk using the 

NSUserDefaults

 class, too. It should then write the data it intends to share to the key-value data store using the 

NSUbiquitousKeyValueStore

 class. This ensures that if iCloud is not available, you still have access to the configuration data you need.

For more information about how to use the key-value store in your app, see Preferences and Settings Programming Guide.

Being a Responsible iCloud App

Apps that take advantage of iCloud storage features should act responsibly when storing data there. The space available in each user’s account is limited and is shared by all apps. Users can see how much space is consumed by a given app and choose to delete documents and data associated with your app. For these reasons, it is in your app’s interest to be responsible about what files you store. Here are some tips to help you manage documents appropriately:

  • Have a good strategy for storing iCloud documents. Whenever possible, give the user a single option to store all data in iCloud.
  • Deleting a document removes it from a user’s iCloud account and from all of that user’s computers and devices. Make sure that users are aware of this fact and confirm any delete operations. If you want to refresh the local copy of a document, use the

    evictUbiquitousItemAtURL:error:

     method of 

    NSFileManager

     instead of deleting the file.
  • When storing documents in iCloud, place them in the 

    Documents

     subdirectory whenever possible. Documents inside a 

    Documents

     directory can be deleted individually by the user to free up space. However, everything outside that directory is treated as data and must be deleted all at once.
  • Never store caches or other files that are private to your app in a user’s iCloud storage. A user’s iCloud account should be used only for storing user-related data and content that cannot be re-created by your app.
  • Treat files in iCloud the same way you treat all other files in your app sandbox. The time at which to save a file should be driven by the need of your app and the need to preserve the user’s data. You should not change your app to save files more or less frequently for iCloud. iCloud automatically optimizes its transfers to the server to ensure the best possible performance.
  • In the iCloud key-value store, the maximum number of keys has been raised to 256.
  • All newly generated provisioning profiles are now automatically enabled for iCloud. If you are using an Xcode managed Team Provisioning Profile, click refresh in the Xcode Organizer to obtain a new iCloud-enabled profile. To enable all other provisioning profiles for iCloud, simply regenerate your profiles in the iOS Provisioning Portal.