Automating CloudKit Development

This document describes CloudKit tools and authentication considerations for automating processes to support local integration testing and continuous integration (CI) systems.

cktool

This native macOS application gives you access to features provided in the CloudKit Console API, facilitating CloudKit setup operations for local development and integration testing. With this tool, you or your users can:

  • Reset Sandbox databases to the production configuration.
  • Apply a CloudKit schema file to Sandbox databases (for more information on CloudKit schema files, see Integrating a Text-Based Schema into Your Workflow).
  • Hydrate databases with test data.
  • Run integration tests from Xcode or your CI system.

Authentication

To use cktool for automation, you first need to configure the tool with CloudKit using the authentication mechanisms described in the table below.

Management token

A CloudKit management token is scoped to a team and user. These tokens allow access to the public database and CloudKit management APIs. The management tokens have a default lifespan of one year and can be revoked from the Settings section of the CloudKit Dashboard.

User token

A user token is scoped to a team and container. It’s created only upon interactive login and getting one typically cannot be automated. The user token is also only available in the native macOS CLI, because user interaction is required to authenticate a user and generate a user token. User tokens are short lived and may require re-authentication during a session.

Management token User token
Bound to team
Bound to container
Bound to environment
Bound to user
Can query public database
Can query private database
Can query shared database
Can access management API

Using cktool

Before you begin

  • You'll need to be a current member of the Apple Developer Program or the Apple Developer Enterprise Program in order to use cktool.
  • Understand the concepts of Authentication, as described above.
  • Generate a CloudKit Management Token from the CloudKit Console by choosing the Settings section for your user account. Save this token, as it will not be visible again.

Installing the application

By default, cktool is distributed with Xcode starting with Xcode 13, which is available on the Mac App Store.

General usage

cktool is stateless and passes all operations to the CloudKit Management API in single operations. A full list of supported operations is available from the help command or the man pages:

xcrun cktool --help
OVERVIEW: CloudKit Command Line Tool

USAGE: cktool <subcommand>

OPTIONS:
	-h, --help				Show help information.

SUBCOMMANDS: ...

Authenticating cktool to CloudKit

cktool supports both management and user tokens, and will store them securely in the KeyChain. You can add a token using the save-token command, which will launch CloudKit Console for copying of the appropriate token after prompting for information from the user:

xcrun cktool save-token			\
	--type [management | user]

Issuing Schema Management commands

Schema Management commands require the Management Token to be provided. Once provided, cktool can perform the following commands:

Reset development schema. This allows you to revert the development database to the current production definition.

xcrun cktool reset-schema	\
	--team-id [TEAM-ID]		\
	--container-id [CONTAINER]

Export schema file. This allows you to save an existing CloudKit Database schema definition to a file, which can be kept alongside the related source code:

xcrun cktool export-schema 		\
	--team-id [TEAM-ID]			\
	--container-id [CONTAINER]	\
	--environment [development | production]	\
	[--output-file schema.ckdb]

Importing a schema file. This applies a file-based schema definition against the development database for testing.

xcrun cktool import-schema 		\
	--team-id [TEAM-ID]			\
	--container-id [CONTAINER]	\
	--environment development 	\
	--file schema.ckdb

Issuing data commands

When a user token is available, cktool can access public and private databases on behalf of the user. This can be used for fetching data and inserting new records prior to integration tests. Note that due to the short lifespan of the user token, frequent interactive authentication may be required.

Querying records can be performed with the query-records command. Note that queries without filters require the ___recordID to have a Queryable index applied, as do fields specified in the optional --filters argument:

xcrun cktool query-records		\
	--team-id [TEAMID] 			\
	--container-id [CONTAINER] 	\
	--zone-name [ZONE_NAME] 		\
	--database-type [public | private] 	\
	--environment [development | production]	\
	--record-type [RECORD_TYPE]	\
	[--filters [FILTER_1] [FILTER_2]]

Where FILTER_1 is in the form "[FIELD_NAME] [OPERATOR] [VALUE]", for example "lastname == Appleseed".

Inserting data is accomplished with the create-record command:

xcrun cktool create-record		\
	--team-id [TEAM_ID]			\
	--container-id [CONTAINER]	\
	--zone-name [ZONE_NAME] 		\
	--database-type [public | private] 	\
	--environment [development | production]	\
	--record-type [RECORD_TYPE]	\
	[--fields-json [FIELDS_JSON]]

Where FIELDS_JSON is a JSON representation of the fields to set in the record. For example:

'{
	"firstName": {
	"type": "stringType",
	"value": "Johnny"
  },
	"lastName": {
	"type": "stringType",
	"value": "Appleseed"
  }
}'