Sharing Core Data With CloudKit in SwiftUI

Learn to share data between CoreData and CloudKit in a SwiftUI app. By Marc Aupont.

4.7 (9) · 5 Reviews

Download materials
Save for later
Share

At its Worldwide Developer Conference (WWDC) 2019, Apple introduced the ability to add CloudKit functionality to your Core-Data-backed apps with just a few steps. In theory, you needed only three steps. First, update your container type to NSPersistentCloudKitContainer. Second, enable the iCloud capability in your app. Third, create an iCloud container that hosts your data in iCloud.

Once you’ve completed these steps, the data in your app then “automagically” sync with iCloud. Amazing! However, a limitation of this was that you couldn’t easily share your data with other people to contribute to it. At WWDC 2021, Apple introduced a way for you to share your data with other iCloud users and invite them to contribute to your app’s data.

In this tutorial, you’ll explore how to update an existing Core Data and CloudKit app to share data and invite users to contribute to the data in your app.

  • A paid developer account — To use CloudKit.
  • Two separate iCloud accounts — To initiate the sharing process.
  • At least one real device – To send and accept share invitation(s). Also, to change the sharing permissions because it doesn’t work properly on a simulator.
Note: You’ll need the following prerequisites to complete this tutorial.
  • A paid developer account — To use CloudKit.
  • Two separate iCloud accounts — To initiate the sharing process.
  • At least one real device – To send and accept share invitation(s). Also, to change the sharing permissions because it doesn’t work properly on a simulator.

Getting Started

Download the starter project by clicking the Download Materials button at the top or bottom of this tutorial. Then, open the starter project. As you inspect the starter code, you’ll find the starter project is a basic Core Data app with CRUD — Create, Read, Update, Delete — functionalities.

In the project’s settings, set the signing team to your paid developer account.

Build and run. You see a travel journal screen with an empty state message and a button.

App screen without records

Tap the Add Destination button. This takes you to a screen to add a recent destination you visited. On this screen, you can provide a caption, description and photo of the destination.

Add Destination screen

Once you add a destination, you’ll see it on the main screen like below.

Destination added in a simulator

To delete the destination, swipe left to reveal the delete button. Tapping this button removes a destination from your travel journal.

To edit or update the caption or description, tap the destination cell to see the detail screen. From this screen, you can take a few actions.

At the top right is the edit button, which presents a modal to edit your destination’s caption and description. There’s also a share action that does nothing now. You’ll build this action in this tutorial.

Types of CloudKit Databases

Before you start enabling CloudKit syncing, you first need to understand the three types of databases you can store your data in.

  • Public: Data stored here is public, and every user, whether they sign in to the iCloud account or not, can read it. You’ll store data in this database for this tutorial.
  • Private: Data stored here is private data associated with the currently signed-in user.
  • Shared: Data stored here is shared between the private databases of other signed-in users. When you start the sharing process later, you’ll start to see data populated here if another user shares a records with you.

Enabling CloudKit Syncing

The next step of preparing your shared data is to enable storing your data in iCloud. When you create a destination, the data is being persisted via Core Data locally in your app.

In the Signing & Capabilities section, add the iCloud capability. You’ll need to ensure that you have set a unique bundle identifier at this point. Then, select the CloudKit checkbox to enable the feature.

iCloud capability added and CloudKit enabled

The next step is to create the container your data will live in. In the iCloud section, tap the + button underneath Containers to add a custom container. In the window that comes up, enter your container’s name. A general guideline is to use com.company_name.bundle_identifier. Xcode prefixes the container name with iCloud.

Add a new container for iCloud container

The final step is to add the Background Modes capability and enable Remote Notifications. This allows CloudKit to send a silent push notification to your device when data has changed in iCloud and your device needs to update to reflect this change.

Remote notifications added in Capabilities

Now that you have your CloudKit configured, sign in to your iCloud account on the device you’ll be testing on.

Launch a simulator. From the home screen, open Settings. Sign in to your Apple ID.

Build and run. Add a destination.

Add Destination animated gif

Last, head to the CloudKit Console so you can verify your data.

CloudKit Console main page

CloudKit Console Dashboard

When storing data via CloudKit, CloudKit Console allows you to interact with the data in question and perform several other functions such as viewing logs. After you have logged into the console, open CloudKit Database.

Once you’re in this section, you need to specify the container you want to see. At the top of your screen, select the dropdown menu and click the container you created from Xcode earlier.

Below the Data section, click Records. Select Private Database. This is the default database that data gets written to.

Select Private Database in CloudKit Console

If you attempt to select record type as CD_Destination and query records from here, you receive an error stating Field recordName isn’t marked queryable. Now, you’ll resolve this error.

Under the Schema section, select Indexes. Select CD_Destination. This is your Destination entity in Core Data. CloudKit prefixes your entities with CD to distinguish them from traditional CloudKit records.

Click Add Basic Index. Select recordName from the list and ensure the index type is Queryable. Save the changes.

Add a basic index in the CloudKit Console

Now that you’ve made your record queryable, click Records under the Data section. Select Private Database. Specify record type as CD_Destination. Update the selected zone from defaultZone to the automatically generated com.apple.coredata.cloudkit.zone.

Click Query Records to see a listing of the record(s) you created in the app earlier! The most amazing part is that because your data is now synced in iCloud, you can run your app on a completely different device that’s signed in to the same iCloud account and see all your data!

Viewing records in the CloudKit Dashboard