How to Work With CloudKit

At last year’s WWDC event, Apple announced CloudKit. The CloudKit definition is quite simple: it's a framework, which provides API for transferring data from devices running on iOS to Apple’s servers or iCloud. The latter is Apple’s response to the third party cloud storage solutions, such as Microsoft Azure, Google Cloud Platform, Amazon Web Services, and BaaS platforms like Parse. Before iOS developers had no other choice but to turn to Apple’s competitors. But now development with CloudKit have simplified their work with cloud components into their mobile apps.

CloudKit developer and user see CloudKit in different lights. A developer considers CloudKit as a data storage service, a transportation mechanism, and an iOS framework. Whereas for users CloudKit may mean a new public/private experience and a new part of Apple ecosystem.

We couldn’t resist investigating working with CloudKit patterns share it with you. We also created a CloundKit demo project in Objective-C and Swift!

CloudKit Architecture Giude

The main concept in CloudKit is a container — a class that encapsulates content associated with an app and corresponds to a certain place on iCloud server. The container stores and receives data sent from the app, including content that is publicly accessible to all users of the app and content that is private to a specific user. In other words, the container enables communication between the app and the server.


A few apps may have a single container while a single app may have access to a few containers. What is more, the container helps to protect and isolate the data of one app from that of the other, as well as prevents an unauthorized interception of data.

Each app has at least one container by default, which can be accessed through CKContainer class.

Note: When setting up a project in Xcode an examination procedure will be carried out to ensure the availability of an appropriate container. In case such container can’t be found, it will automatically be created and named by Xcode based on the Bundle ID of your app.

Database (class CKDatabase) is a channel for transferring data from the app to the container and visa versa. Each container has both a default public database and a private one, accessible to a single user.

CloudKit containers

Note: Each user uses a private database when working with notes, contacts, and so on, through iCloud.

With the help of the CKDatabase class, you can perform requests needed to work with CloudKit.

A basic initialization of the objects for working with a server is performed in the following way:

CKContainer *container = [CKContainer defaultContainer];
CKDatabase *publicDatabase = [container publicCloudDatabase];
CKDatabase *privateDatabase = [container privateCloudDatabase];

How to set up Cloud/CloudKit?

1.1. Login to iOS Developer Portal.

1.2. Get the list of apps. Here you can either create a new app and set it up for iCloud, or change the settings for an already created app. Let’s press “+” to create a new app.

1.3. Fill in the form “Registering an App ID”. Fill out App ID Description, mark Explicit App ID (set by default), and fill in Bundle ID field.

Now let’s go to the list “App Services”.

Mark iCloud. Then, choose the field “Include CloudKit support” (requires Xcode 6). Press “Continue”.

1.4. Look at the table “Confirm your App ID.”

iCloud is highlighted in yellow, which means that this service is not yet active and needs a further set up. Press “Submit”. Confirm the data and press “Done”.

This is how we just created an app which works with iCloud. Now click on this app and press “Edit.”

1.5. Find “iCloud” tab in the table “Setup and configure services for this App ID”.

After you press “Edit” you will have to bind your app with a certain container.

1.6. How to add a container? Press “iCloud Containers” in the left menu. You will get a table “iCloud Container Total”. Press “+”.

Now you’ll have to fill in Description and ID.

Container is a class with isolated data which encapsulates information it receives from the app. This data is recorded into cloud from a client. By default, a single program can save its data in a single container. The data located in different containers isn’t connected.

Fill in all the fields and press “Continue.” Check if everything is correct and press “Register”.

1.7. Come back to the list of apps (“App IDs” in the left menu).

Again choose the app you created and press “Edit”. Then, find “iCloud” and press “Edit”. Here you go with a table “iCloud Container Assignment” with a list of the available containers.

Mark a container you need and press “Continue”. Check if everything is correct and press

“Assign”. You’ll see a message “You have successfully modified your iCloud Containers.”

1.8. Go to iTunesConnect and press My Apps.

  • Press “+” and choose New iOS App. The dashboard for the app’s CloudKit won’t work if you don’t set it up in iTunesConnect.
  • Fill in the fields in the table “New iOS App”, and press “Create”.
  • Now we have set up the app for CloudKit/iCloud!

Time to go to iCloud developer dashboard.

cloudkit dashboard

Read also: What Parse offers

How to create a project with support for iCloud/CloudKit

To create such a project, check our step-by-step developer documentation:

2.1. Create a new iOS project in Xcode and go to the settings. Insert bundle and choose a corresponding Team, which you can set up in Xcode 6.

It’s important that your app’s bundle id and iCloud containers match and can be reached in the developer account. For example, if a bundle identifier is “com.<your domain>.BabiFud”, a name for the iCloud container should be “iCloud” + the id of the bundle: “<your domain>.BabiFud”.

The app will work only if you meet all the conditions in the settings.

Read alsoMastering UIKit performance

2.2. Implement testing requests.

How to request data:

CKContainer *defaultContainer = [CKContainer defaultContainer];
 NSPredicate *predicate = [NSPredicate predicateWithFormat:@"TRUEPREDICATE"];
 CKDatabase *publicDatabase = [defaultContainer publicCloudDatabase];
 CKQuery *query = [[CKQuery alloc] initWithRecordType:@"Post" predicate:predicate];
 [publicDatabase performQuery:query inZoneWithID:nil completionHandler:^(NSArray *results, NSError *error) {
 if (!error) {
 NSLog(@"%@", results);
 } else {
 NSLog(@"%@", error);

How to add data:

CKRecordID *recordID = [[CKRecordID alloc] initWithRecordName:@"1"];
 CKRecord *postRecrod = [[CKRecord alloc] initWithRecordType:@"Post" recordID:recordID];
 postRecrod[@"postText"] = @"Sample point of interest";
 postRecrod[@"postTitle"] = @"My favorite point of interest";
 CKDatabase *publicDatabase = [[CKContainer defaultContainer] publicCloudDatabase];
 [publicDatabase saveRecord:postRecrod completionHandler:^(CKRecord *record, NSError *error) {
 if(error) {
 NSLog(@"%@", error);
 } else {
 NSLog(@"Saved successfully");

How to update data:

CKContainer *defaultContainer = [CKContainer defaultContainer];
CKDatabase *publicDatabase = [defaultContainer publicCloudDatabase];
CKRecordID *recordID = [[CKRecordID alloc] initWithRecordName:@"1"];
[publicDatabase fetchRecordWithID:recordID completionHandler:^(CKRecord *record, NSError *error) {
 if(error) {
 NSLog(@"%@", error);
 } else {
 record[@"postText"] = @"123 Beggers Canyon, Tatooine";;
 [publicDatabase saveRecord:record completionHandler:^(CKRecord *record, NSError *error) {
 if(error) {
 NSLog(@"Uh oh, there was an error updating ... %@", error);
 } else {
 NSLog(@"Updated record successfully");

Deleting the ID record:

CKContainer *defaultContainer = [CKContainer defaultContainer];
 CKDatabase *publicDatabase = [defaultContainer publicCloudDatabase];
 CKRecordID *recordID = [[CKRecordID alloc] initWithRecordName:@"1"];
 [publicDatabase deleteRecordWithID:recordID completionHandler:^(CKRecordID *recordID, NSError *error) {
 if(error) {
 NSLog(@"%@", error);
 } else {
 NSLog(@"Deleted record successfully")

You can check the presentation on setting up CloudKit.

Read alsoComparing 4 mBaaS platforms

At present CloudKit framework can only do one thing — transfer the data. But in the future working with CloudKit may bring lots of advantages. We’ll be looking forward to more considerable updates to the framework from Apple. In our next blog post, we are going to compare CloudKit with Parse. So keep up with our blog updates!

In the meanwhile, check the CloudKit Objective-C example project as well as Swift example.

3.0/ 5.0
Article rating
Remember those Facebook reactions? Well, we aren't Facebook but we love reactions too. They can give us valuable insights on how to improve what we're doing. Whould you tell us how you feel about this article?