An encapsulation of content associated with an app, including content that is accessible to all users and content that is available only to a specific user.
- iOS 8.0+
- macOS 10.10+
- tvOS 9.0+
- watchOS 2.0+
A container object manages all explicit and implicit attempts to access the contents of the container.
Every app has a default container object that manages its own native content. If you develop a suite of apps, you can also access any container objects for which you have the appropriate entitlements. Each new container distinguishes between publicly available data and data that is private to the current user. Private data is always stored in the appropriate container directory in the user’s iCloud account.
Interacting with a Container Object
A container object coordinates all interactions between your app and the server. Most of these interactions involve the following tasks:
Determining whether the user has configured an iCloud account for the device, which lets you know if you can write data to the user’s personal storage.
With the user’s permission, discovering other users that are known to the current user and making the user’s information discoverable.
Getting the container or one of its
CKDatabaseobjects so that you can assign it explicitly to an operation object
Public and Private Databases
Each container contains links to a public and private database for storing data. The contents of the public database are accessible to all users of the app, whereas the contents of the private database are by default visible only to the current user. Content that is specific to a single user usually belongs in that user’s private database, whereas app-related content that you provide (or that users want to share) belongs in the public database.
The public database is always available, regardless of whether the device has an active iCloud account. When no iCloud account is available, your app may fetch records from and query the public database, but it may not save changes. (Saving records to the public database requires an active iCloud account to identify the owner of those records.) Access to the private database always requires an active iCloud account on the device.
Whenever possible, design your app to run gracefully with or without an active iCloud account. Even without an active iCloud account, apps can fetch records from the public database and display that information to the user. If your app requires the ability to write to the public database or requires access to the private database, notify the user of why that is the case and encourage them to enable iCloud. You can even provide a button that takes the user directly to Settings so that they can enable iCloud. To implement such a button, have the button’s action open the URL represented by the
User Records and Permissions
Every user who accesses a container has a corresponding user record in that container. By default, user records contain no identifying personal information about the user or their iCloud account. User records provide a way to differentiate one user of the app from another through the use of a unique identifier. Every user gets their own unique identifier in a container. Because there is a record that has the same identifier as the user identifier, you can use the record to store information about the current user. Always do so carefully, though, and with the understanding that any data you add to the user record can be seen by other users of the app. Never store sensitive personal information in the user record. This user record is not to be confused with the user’s
CKUser, which is a separate record and by default does not contain any personally identifying information.
Testing Your Code Using the Development Container
At runtime, CloudKit uses your app’s
com entitlement to discover whether you are using a
Production version of your provisioning profile. When the entitlement is configured for development, CloudKit configures the app’s
CKContainer objects to talk to the development server. The development environment is intended to be a safe place to make changes during the development process without disrupting active users of your app. You can add new fields to records programmatically and you can delete or modify fields using iCloud Dashboard.
Before shipping your app, always test your app’s behavior in the production environment. The production server generates errors when your app tries to add record types or add new fields to existing record types. Testing in the production environment helps you find and fix the places in your code where you are making those types of changes. You can use CloudKit Dashboard to modify record types in the development environment and then migrate those changes to the production environment.