CloudKit is an amazing framework and Apple has proven that it's a robust, reliable solution for persisting data in the cloud. Several of the company's flagship applications are powered by CloudKit, including iCloud Drive, Photos, and Notes.
Despite the many advantages the framework brings to the table, I feel CloudKit isn't as popular as it could be. The primary reason is that the framework has a steep learning curve. The API is quite daunting and, more importantly, there isn't a clear path developers can stick to. There are many ingredients but no recipe.
Getting Started
Getting started with CloudKit is easy thanks to Xcode's tight integration with Apple's developer website. Working with the CloudKit API is bit more challenging. The API isn't particularly complex. The challenge lies not so much in understanding the framework as in pieces everything together. You, the developer, need to do the hard work.
Let me make one thing clear. CloudKit is a solution to transport data from and to Apple's iCloud servers. That's it. If you want to integrate CloudKit with Core Data, then you have work to do. And there's no recipe you can follow. The lack of a blueprint is what scares many developers away from the framework.
In the coming weeks, I plan to release a series of tutorials on CloudKit to help developers interested in CloudKit become more familiar with the framework. We start with the basics, enabling CloudKit in a project, and cover several aspects that are typical to most CloudKit applications. We won't build a functional application during this series since every application uses CloudKit a bit differently. The focus lies on solving common problems you face when adopting CloudKit.
Let's Get Started
To kick this series off, I'd like to show you how easy it is to enable CloudKit in a project, new or existing.
Creating the Project
Fire up Xcode, create a new project based on the Single View App template, and name the project Scribbles.
Tell Xcode where you'd like to store the project and hit Create.
Enabling CloudKit
To enable CloudKit, we first need to flip the iCloud switch in the Capabilities tab of the Scribbles target.
The iCloud section shows us that key-value storage is enabled by default. Check the CloudKit checkbox to enable CloudKit for the Scribbles target.
Xcode immediately jumps into action behind the scenes, performing several steps you used to take care of manually. Every CloudKit application has its own iCloud container. An iCloud container is similar to the sandbox or container on the user's device. It ensures the data of your application is isolated on Apple's iCloud servers.
You can also give your application access to the iCloud container of another application that's linked to your developer account. This is interesting, for example, if you're developing a mobile client for a desktop application.
Done For You
Earlier, I mentioned that Xcode performs several steps behind the scenes. It create an App ID for you, enables iCloud for that App ID, and it adds the App ID to the iCloud container it created for your application.
Xcode also created an entitlements file for the Scribbles target and added the iCloud entitlement to it. The Scribbles target is also linked against the CloudKit framework.
In short, the project is ready to take advantage of the CloudKit framework and services. Let's give it a try.
Talking to Apple's Servers
Later in this series, we discuss account management in more detail. For now, make sure you're signed in with a valid Apple ID on the device you're using for development.
Open ViewController.swift and add an import statement for the CloudKit framework at the top.
import UIKit
import CloudKit
class ViewController: UIViewController {
}
To show you that CloudKit is enabled and set up correctly, we're going to fetch the record identifier of the user that's signed in on the device. We need to ask the iCloud container for this information. We can access the iCloud container that's linked to the application through the CKContainer
class.
Remember that we configured CloudKit to use the default container, that is, the container that's assigned to this application. We can obtain a reference to this container by invoking the default()
method.
import UIKit
import CloudKit
class ViewController: UIViewController {
// MARK: - View Life Cycle
override func viewDidLoad() {
super.viewDidLoad()
CKContainer.default()
}
}
To fetch the record identifier for the currently signed in user, we invoke fetchUserRecordID(_:)
on the default container. This method accepts one argument, a closure. This closure is invoked when the asynchronous request completes, successfully or unsuccessfully. It accepts two arguments, the optional record identifier and an optional error.
import UIKit
import CloudKit
class ViewController: UIViewController {
// MARK: - View Life Cycle
override func viewDidLoad() {
super.viewDidLoad()
CKContainer.default().fetchUserRecordID { (recordID, error) in
if let error = error {
print(error)
} else if let recordID = recordID {
print(recordID)
}
}
}
}
Run the application on your device and inspect the output in the console. This is what the result should look like. Later in this series, you learn more about record names and record zones. Don't worry about these details for now.
<CKRecordID: 0x1c00371a0; recordName=_e9301d882e4b36774e521e5e992a06ec, zoneID=_defaultZone:__defaultOwner__>
An Easy Start
I hope you agree that getting up and running with CloudKit is easy. Xcode takes care of the nitty gritty details and we can focus on integrating with Apple's iCloud infrastructure.
Once you start using CloudKit, however, you'll notice that this is the easiest step. The CloudKit API isn't difficult to use or understand, but there are many details you need to take into account.