CloudKit Tutorial: Getting Started

In this CloudKit tutorial, you’ll learn how to add and query data in iCloud from your app, as well as how to manage that data using the CloudKit dashboard. By Andy Pereira.

Leave a rating/review
Download materials
Save for later
Share
Update note: Andy Pereira updated this tutorial for Xcode 11, iOS 13 and Swift 5.1. Michael Katz wrote the original.

CloudKit is Apple’s remote data storage service. Based on iCloud, it provides a low-cost option to store and share app data using your users’ iCloud accounts as a back-end storage service.

There are two main components to CloudKit:

  1. A web dashboard to manage record types and any public data.
  2. A set of APIs to transfer data between iCloud and the device.

With CloudKit, users’ private data is completely protected because developers can only access their own private databases and aren’t able to look at any user’s private data.

CloudKit is a good option for iOS-only apps that use a lot of data but don’t require a great deal of server-side logic. In addition, you can use CloudKit for web and server apps.

In this CloudKit tutorial, you’ll get hands-on experience using CloudKit by creating a restaurant rating app with a twist, called BabiFüd.

Note: To work with the sample app in this CloudKit tutorial, you’ll need an active iOS developer account. Without one, you won’t be able to enable the iCloud entitlements or access the CloudKit dashboard.

Why CloudKit?

You might wonder why you should choose CloudKit over other commercial BaaS (Backend as a Service) offerings, or even rolling your own server.

There are three reasons: Simplicity, trust and cost.

Simplicity

Unlike other back-end solutions, CloudKit requires little setup. You don’t have to choose, configure or install servers. Apple handles security and scaling as well.

Simply registering for the iOS Developer Program makes you eligible to use CloudKit. You don’t have to register for additional services or create new accounts. When you enable CloudKit capabilities in your app, all necessary server setup magic happens automatically.

There’s no need to download additional libraries and configure them; you import CloudKit like any other iOS framework. The CloudKit framework itself also provides a level of simplicity by offering convenient APIs for common operations.

It’s also easy for users. Since CloudKit uses the iCloud credentials that users enter when they set up their devices (or that they enter after setup via the Settings app), there’s no need to build complicated login screens. As long as they are logged in, users can use your app seamlessly. That should put you on Cloud 9!

Trust

Another benefit of CloudKit is that users can trust the privacy and security of their data by relying on Apple rather than app developers. CloudKit insulates user data from you, the developer.

While this lack of access can be frustrating while debugging, it’s a net plus since you don’t have to worry about security or convince users their data is secure. If an app user trusts iCloud, then they can also trust you.

Cost

Finally, the cost of running a service is a huge deal for any developer. Even the least-expensive server hosts can’t offer low-cost solutions for small, free or cheap apps. So there will always be a cost associated with running an app.

With CloudKit, you get a reasonable amount of storage and data transfer of public data for free. There’s a handy calculator on Apple’s CloudKit site.

These strengths make the CloudKit service a low-hassle solution for Mac and iOS apps.

Introducing BabiFüd

The sample app for this CloudKit tutorial, BabiFüd, is the freshest take on the standard “rate a restaurant” app. Instead of reviewing restaurants based upon food quality, speed of service or price, users rate child-friendliness. This includes the availability of changing facilities, booster seats and healthy food options.

The app contains two tabs: A list of nearby restaurants and user-generated notes. You can get a glimpse of the app in action below.

cloudkit tutorial sample app
cloudkit tutorial sample app

A model class backs these views and wraps the calls to CloudKit. CloudKit objects are called records. The main record type in your model is an Establishment, which represents the various restaurants in your app.

Getting Started

Use the Download Materials button at the top or bottom of this tutorial to download the starter project.

You’ll have to change the Bundle Identifier and Team of your app before you can start coding. You need to set the team to get the necessary entitlements from Apple, while having a unique bundle identifier makes the process a whole lot easier.

Open BabiFud.xcodeproj in Xcode. Select the BabiFud project in the Project navigator, then select the BabiFud target. With the General tab selected, replace the Bundle Identifier with something unique. Standard practice is to use reverse domain name notation and include the project name.

Setting the bundle ID for this CloudKit tutorial

That takes care of the Bundle Identifier. Now, you’ll need to get your app set up for CloudKit and create some containers to hold your data.

Entitlements and Containers

You’ll need a container to hold the app’s records before you can add any data via your app. A container is the term for the conceptual location of all the app’s data on the server. It’s a group of public and private databases.

CloudKit tutorial CloudKit container diagram

To create a container, you first need to enable the iCloud entitlements for your app:

  1. Select the Signing & Capabilities tab in the target editor.
  2. Click on + Capability.
  3. Choose iCloud.
  4. Select your Team from the drop-down.

Adding CloudKit capability in Xcode 11

At this point, Xcode might prompt you to enter the Apple ID associated with your iOS developer account. If so, then type it in as requested.

Next, enable CloudKit by checking the CloudKit checkbox in the Services group.

Adding CloudKit capability in Xcode 11

Finally, click on + under Containers to add a new container, if CloudKit didn’t automatically create one for you.

Adding CloudKit capability in Xcode 11

In the pop-up, add your bundle identifier.

Adding a CloudKit container in Xcode 11

This creates a default container named iCloud.<your app’s bundle ID>.

Note: At the time of writing, CloudKit containers cannot be deleted. Keep in mind that if you create a new container for this tutorial, it will live on forever in your CloudKit Dashboard.

Troubleshooting iCloud Setup in Xcode

If you see any warnings or errors related to the container ID when creating entitlements, building the project or running the app, here are some troubleshooting tips:

Normally, Xcode does all of this automatically if you are signed in to a valid developer account. Unfortunately, this sometimes gets out of sync.

It can help to start with a fresh ID and, using the iCloud capabilities pane, change the CloudKit container ID to match. Otherwise, you may have to edit the Info.plist or BabiFud.entitlements files to make sure the ID values there reflect what you set for the bundle ID.

  • If there are any warnings or errors shown in the Steps group in the iCloud section, try pressing the Fix Issue button. You might need to do this a few times.
  • The app’s bundle ID and iCloud containers must match and they must exist in the developer account. For example, if the bundle identifier is com.<your domain>.BabiFud, then the iCloud container name should be iCloud. plus the bundle bundle id: iCloud.com.<your domain>.BabiFud.
  • The iCloud container name must be unique because this is the global identifier used by CloudKit to access the data. Since the iCloud container name contains the bundle ID, the bundle ID must also be unique. This is why you cannot use com.raywenderlich.BabiFud and you had to change it earlier.
  • For the entitlements to work, the app/bundle ID has to appear in the App IDs portion of the Certificates, Identifiers and Profiles portal. This means the certificate used to sign the app has to be from the set team ID and has to list the app ID, which also implies the iCloud container ID.

    Normally, Xcode does all of this automatically if you are signed in to a valid developer account. Unfortunately, this sometimes gets out of sync.

    It can help to start with a fresh ID and, using the iCloud capabilities pane, change the CloudKit container ID to match. Otherwise, you may have to edit the Info.plist or BabiFud.entitlements files to make sure the ID values there reflect what you set for the bundle ID.