From the perspective of the average iPhone or iPad owner, iCloud represents a vast, remote storage service onto which device-based data may be backed up and music stored for subsequent streaming to multiple iCloudsupported platforms and devices.
From the iOS app developer’s perspective, iCloud represents a set of programming interfaces and SDK classes that facilitate the storage of files and data on iCloud servers hosted at Apple’s data centers from within an iOS app.
This chapter is intended to provide an overview of iCloud and to walk through the steps involved in preparing an iOS app to utilize the services of iCloud.
iCloud Data Storage Services
The current version of the iOS SDK provides support for four types of iCloud-based storage: iCloud Document Storage, iCloud Key-Value Data Storage, iCloud Drive Storage, and CloudKit Data Storage.
iCloud document storage allows an app to store data files and documents on iCloud in a special area reserved for that app. Once stored, these files may be retrieved from iCloud storage by the same app at any time as long as it runs on a device with the user’s iCloud credentials configured.
The iCloud key-value storage service allows small amounts of data packaged in key/value format to be stored in the cloud. This service is intended to provide a way for the same app to synchronize user settings and status when installed on multiple devices. A user might, for example, have the same game app installed on an iPhone and an iPad. The game app would use iCloud key-value storage to synchronize the player’s current position in the game and the prevailing score, thereby allowing the user to switch between devices and resume the game from the same state.
Every Apple user account has associated with it an iCloud Drive storage area into which files may be stored and accessed from different devices and apps. Unlike files stored using the iCloud Storage option (which is generally only accessible to the app that saved the file), however, files stored on iCloud Drive can also be accessed via the built-in Files app on iOS, other apps, the Finder on macOS, the iCloud Drive app on Windows and even via the iCloud.com web portal. Saving files to iCloud Drive will be outlined in the chapter entitled “Using iCloud Drive Storage in an iOS 16 App”.
CloudKit data storage provides apps with access to the iCloud servers hosted by Apple. It provides an easy-to-use way to store, manage and retrieve data and other asset types (such as large binary files, videos, and images) in a structured way. This allows users to store private data and access it from multiple devices and for the developer to provide publicly available data to all app users. CloudKit data storage is covered in detail, beginning with the chapter entitled An Introduction to CloudKit Data Storage on iOS 16.
Preparing an App to Use iCloud Storage
For an app to use iCloud services, it must be code signed with an App ID with iCloud support enabled. In addition to enabling iCloud support within the App ID, the app must also be configured with specific entitlements to enable one or more of the iCloud storage services outlined in the preceding section of this chapter.
Fortunately, both of these tasks can be performed within the Capabilities screen within Xcode 14.
Clearly, iOS developers who are not yet members of the iOS Developer Program will need to enroll before implementing any iCloud functionality. Details on enrolling in this program were outlined in the How to Join the Apple Developer Program chapter of this book.
Enabling iCloud Support for an iOS 16 App
To enable iCloud support for an app, load the project into Xcode and select the app name target from the top of the project navigator panel (marked A in Figure 39-1). Then, from the resulting project settings panel, select the Signing & Capabilities tab (B) followed by the target entry (C):
Click on the “+ Capability” button (D) to display the dialog shown in Figure 39-2. Next, enter iCloud into the filter bar, select the result, and press the keyboard enter key to add the capability to the project:
Once you have enabled iCloud, the capabilities section provides options to enable key-value storage, iCloud Documents (which enables both the iCloud Storage and iCloud Drive capabilities), and CloudKit services. This is also where the iCloud containers used to store data are created and managed:
Enabling iCloud support will have automatically added the iCloud entitlement to the app’s App ID and created an entitlements file to the project containing the app’s iCloud container identifiers.
Reviewing the iCloud Entitlements File
Once iCloud capabilities have been enabled for an app within Xcode, a new file will appear in the project named <product name>.entitlements. Any apps that intend to use iCloud storage in any way must obtain entitlements appropriate to the iCloud features to be used. These entitlements are placed into this entitlements file and built into the app at compile time.
If the app is intended to use iCloud document storage, then the entitlements file must include a request for the com.apple.developer.icloud-container-identifiers entitlement. Similarly, if the key-value store is to be used, then the com.apple.developer.ubiquity-kvstore-identifier entitlement must be included. Apps that require both forms of iCloud storage must include both entitlements.
The entitlements file is an XML file in which the requests are stored in a key-value format. The keys are the entitlement identifiers outlined above, and the values are represented by one or more container identifiers comprised of the developer’s ID and a custom string that uniquely identifies the app (the corresponding app’s App ID is generally recommended, though not mandatory, for this value).
The entitlements file may be created either manually or, as outlined above, automatically from within the Xcode environment. The entitlements file will appear in the project navigator panel when using the Capabilities settings.
When using the Capabilities panel, a single iCloud container is added to the entitlements file. Additional containers may be added by selecting the Specify custom containers option and clicking on the ‘+’ button located beneath the Containers list.
Accessing Multiple Ubiquity Containers
The ubiquity-container-identifiers value is an array that may reference multiple iCloud containers. If an app requires access to more than one ubiquity container, it will need to reference the identifier of the required container specifically. This is achieved by specifying the container identifier when constructing URL paths to documents within the iCloud storage. For example, the following code fragment defines a container identifier constant and then uses it to obtain the URL of the container in storage:
let UBIQUITY_CONTAINER_URL = "ABCDEF12345.com.yourdomain.icloudapp" let ubiquityURL = FileManager.default.url(forUbiquityContainerIdentifier: UBIQUITY_CONTAINER_URL)?.appendingPathComponent("Documents")
Suppose nil is passed through as an argument in place of the container identifier. In that case, the method will simply return the URL of the first container in the ubiquity-container-identifiers array of the entitlements file:
let ubiquityURL = FileManager.default.url( forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents")
Ubiquity Container URLs
When documents are saved to the cloud, they will be placed in subfolders of a folder on iCloud using the following path:
/private/var/mobile/Library/Mobile Documents/ <ubiquity container id>/Documents
iCloud brings cloud-based storage and app data synchronization to iOS 16-based apps. Before an app can take advantage of iCloud, it must first be provisioned with an iCloud-enabled profile and built against an appropriately configured entitlements file.