In this series we learn about CloudKit, Apple's storage framework that builds on top of iCloud. We'll start with the basics on creating schemas and storing records, how to query efficiently, and how to leverage CloudKit's strengths in an effort to build a connected application without a custom backend.
Length: about 2 hours
The first episode in a new series on CloudKit, here we see how to setup our project to use CloudKit as well as how to create and save our first record.
In order to use CloudKit to read or write private data (or to write in the public database) the user will have to be signed in to iCloud on their device. If they are not, they'll not have a great experience, and things won't work. In this episode we'll check the account status before trying to save a record in CloudKit. We'll also respond to the notification to know when the user's account status has changed so we can react accordingly.
Now that we have saved records in CloudKit, how do we fetch them again? This video covers how to fetch a single record by ID, how to use full-text search to match partial terms, how to return all records (with paging support) and how to query by location.
We learn how to link records together to create relationships between records using CKReference.
We'll wrap our Review record in a model object, then create a method to show all reviews for a given restaurant. We'll then look at how to display the reviews and how to add a new review using the UI.
Working with images in CloudKit can be tricky. There's no server code you can add to process images to create multiple versions, for instance. In this episode we'll see how we can pick an image from the user's photo library and upload them to a new Photo record, which contains original and thumbnail versions of the uploaded picture. We'll leverage some helper methods to automatically translate from a UIImage to a CKAsset and vice-versa.
Fetching records in CloudKit fetch the entire record, including downloading any associated assets. This makes it not feasible to fetch many records at a time. Instead, we'll see how to fetch a subset of each record, keeping the overall size of the request small. We'll also introduce paging to request a single visible set of records at a time.
Saving records includes uploading any attached assets. For a good user experience, we should show the user the progress for any records that are being saved (or downloaded). In this episode we’ll see how we can get that data and show a progress bar for uploading photos. To do this we will take a look at a new class, CKModifyRecordsOperation.
So far in this series we've been using CloudKit directly from our controllers. This can be somewhat limiting. It requires you to be online or everything fails, we may want to add a caching layer, or we might want to use CloudKit as a network synchronization layer, rather than a primary data store. In this episode we'll examine an architecture that will allow you to decouple your view controllers from CloudKit as a first step to achieving more flexibility with your CloudKit implementation.
Since our model objects will be backed by a CKRecord, we will leverage computed properties to marshal values back and forth to the record. Doing so in a type safe way gets pretty redundant, so we can reuse a lot of this boilerplate code by extracting a protocol we’ll call CKRecordWrapper. We can leverage this protocol to give us type-safe access to record keys and to provide default implementations of identifier, modifiedAt, and createdAt fields.
In this episode we implement a CloudKit version of our NotesManager protocol. Along the way we'll implement a reusable query function and run into a limitation with Swift generics that we will have to work around.
We finish the CloudKitNotesManager by providing a generic save and delete methods that we can use for any CKRecordWrapper type. We also implement a custom notification when a note is saved so that we can update an interested view controllers to update their UI.