ハイライト
Apple は cktool と CloudKit 宣言型スキーマ言語を Xcode 13 に追加しました。これにより、開発者はテスト前に CloudKit コンテナを自動的にリセットし、スキーマをインポートし、サンプル データを書き込むことができ、不安定なクラウド統合テスト環境の問題が解決されました。
主要内容
CloudKit アプリケーションの統合テストで最も恐れられるのは、サーバー状態のドリフトです。
ローカル コードによってデータ モデルが変更されており、CloudKit コンテナ内のスキーマが古いバージョンのままになっている可能性があります。テストの最初の実行ではデータが作成され、2 回目の実行では前回残されたレコードが読み取られます。開発者は結局、コンソールのクリーニング、フィールドの同期、サンプル データの再構築に時間を費やすことになり、テスト自体は二次的なタスクになってしまいます。
Apple は WWDC21 で 2 つのツールを発表しました。一つ目はcktool、Xcode 13でインストールされ、経由xcrunコマンドラインからCloudKitにアクセスします。スキーマをインポートおよびエクスポートし、レコードを作成およびクエリできます。 2 つ目は CloudKit スキーマ言語 (CloudKit Schema language) で、コンテナ構造をテキスト ファイルとして記述し、アプリケーション コードとともにバージョン管理に送信できます。
このようにして、スクリプトによって CloudKit テスト環境を準備できます。テストを開始する前に、スクリプトはまず開発環境をクリアし、次にプロジェクトにスキーマ ファイルをインポートし、最後に固定サンプル データを書き込みます。 Xcode のテスト プレアクションは、テストの実行前にこのスクリプトを実行します。テストは毎回同じコンテナーの状態に直面するため、失敗の原因を特定しやすくなります。
コンソール操作をスクリプト操作に変換する
以前は、CloudKit コンソールはコンテナの手動表示と変更に適していました。スキーマ管理を完了できますが、継続的統合プロセスには適していません。また、チーム メンバーが Git diff から CloudKit スキーマの変更を確認することも困難です。
cktoolこれらの操作をコマンドラインに入力します。スキーマのエクスポートもコマンドであり、スキーマのインポートもコマンドです。テスト レコードを作成するときに、JSON を直接渡すことができます。開発者は、テスト前にブラウザを開いたり、コンソールを手動でクリックしたりする必要はありません。
暗黙的なサーバー状態からテキスト ファイルへの変更
スキーマ言語はレコードタイプ、フィールド、インデックス、権限を書き込みます。.ckdbファイル内にあります。このファイルはプロジェクト ディレクトリに配置され、Swift コードと一緒にレビューされます。
アプリケーションのデータ モデルが変更されると、スキーマの変更も同じコミットに入ります。テスト スクリプトはこのファイルをインポートします。サーバーのステータスはリポジトリ内のテキスト宣言から得られるため、チームは誰かがコンソールにアクセスしてフィールドを変更することを忘れずに済みます。
詳細
cktool を承認する
(02:21)cktoolCloudKit サーバーに直接接続し、使用前に認証が必要です。 CloudKit は 2 種類のトークンを提供します。管理トークンは、スキーマのインポートやエクスポートなどのコンテナー構成に使用されます。ユーザー トークンは、アプリケーション コンテナーのプライベート データベースまたはパブリック データベースにデータを書き込むために使用されます。
xcrun cktool save-token --type management
xcrun cktool save-token --type user
xcrun cktool get-teams
キーポイント:
xcrun cktoolXcode 13 によってインストールされた CloudKit コマンド ライン ツールを呼び出します。save-token --type managementスキーマのインポートやエクスポートなどの構成操作のために管理トークンを保存します。save-token --type userコンテナデータにアクセスするためのユーザートークンを保存します。- トークンは macOS キーチェーンに安全に保存されます。
get-teams現在の開発者アカウントが属する Apple 開発者チームのリストを返します。後続のコマンドにはチーム ID が必要です。
CloudKit スキーマのエクスポート
(03:45) コンテナ内に開発中のスキーマがすでにある場合は、まずファイルにエクスポートしてから、ソース コード リポジトリに送信できます。講義内でエクスポートしたファイル名はschema.ckdb。
xcrun cktool export-schema \
--team-id XYZ1234567 \
--container-id iCloud.com.WWDC21.Example \
--environment development \
--output-file schema.ckdb
キーポイント:
export-schemaCloudKit コンテナからスキーマをエクスポートします。--team-id XYZ1234567Apple 開発者チームを指定します。--container-id iCloud.com.WWDC21.Example操作する CloudKit コンテナを指定します。--environment development開発環境を選択します。講演では、開発環境ではレコードタイプとカスタムフィールドを追加したり削除したりできることが強調された。--output-file schema.ckdbエクスポートしたスキーマをテキスト ファイルに書き込み、バージョン管理に簡単に含めることができます。
テスト記録を作成する
(04:07)cktoolデータの書き込みも可能です。 JSON を使用して表現する講義Book記録し、それをパブリック データベースに作成します。
xcrun cktool create-record \
--team-id XYZ1234567 \
--container-id iCloud.com.WWDC21.Example \
--environment development \
--database-type public \
--record-type Book \
--fields-json '{
"title": { "type": "stringType", "value": "Treasure Island" },
"pageCount": { "type": "int64Type", "value": 304 }
}'
キーポイント:
create-recordCloudKit サーバーにレコードを作成します。--database-type publicパブリックデータベースへの書き込みを指定します。--record-type Book指定したレコード タイプは、コンテナ スキーマのレコード タイプと一致している必要があります。--fields-jsonJSON を使用してフィールド値を記述します。title種類はstringType、値はTreasure Island。pageCount種類はint64Type、値は304。
CloudKit の準備手順を Xcode テストに統合する
(05:05) この講義では、コンテナのリセット、プロジェクトへのスキーマ ファイルのインポート、サンプル レコードの作成という 3 種類の操作を Xcode スキームの Test プレアクションに組み込みます。cktoolコマンドは同期的に実行され、前のコマンドが失敗すると、後続のコマンドは実行を継続できなくなります。
xcrun cktool reset-schema \
--team-id XYZ1234567 \
--container-id iCloud.com.WWDC21.Example
xcrun cktool import-schema \
--team-id XYZ1234567 \
--container-id iCloud.com.WWDC21.Example \
--environment development \
--file $PROJECT_DIR/Example/CloudKitSchema.ckdb
xcrun cktool create-record \
--team-id XYZ1234567 \
--container-id iCloud.com.WWDC21.Example \
--environment development \
--database-type public \
--record-type Book \
--fields-json '{
"title": { "type": "stringType", "value": "Great Expectations" },
"pageCount": { "type": "int64Type", "value": 544 },
"description": { "type": "stringType", "value": "Depiction of the education of an orphan nicknamed Pip" },
"publishedOn": { "type": "timestampType", "value": "1860-12-01T03:23:07.415Z" },
"reviewStatus": { "type": "int64Type", "value": 1 }
}'
キーポイント:
reset-schema指定した CloudKit コンテナのスキーマをリセットします。これは、テスト前に開発環境をクリーンアップするのに適しています。import-schemaプロジェクトに投入する.ckdbスキーマ ファイルは CloudKit サーバーに送信されます。$PROJECT_DIR/Example/CloudKitSchema.ckdbXcode ビルド設定を使用して、プロジェクト内のスキーマ ファイルを見つけます。- 2番目
create-recordより完全なものを書くBookサンプルレコード。 publishedOn使用timestampType、値は ISO 時間文字列です。reviewStatus使用int64Type、値は1。- このスクリプトがテストのプレアクションに配置されると、各テストが実行される前に、同じ一連の CloudKit 状態が準備されます。
スキーマ言語ファイルの読み取り
(05:51) スキーマ ファイルには、CloudKit のレコード タイプ、フィールド、インデックス、セキュリティ ロールが記述されています。トーク定義の例Bookレコードタイプ。
DEFINE SCHEMA
RECORD TYPE Book (
"___createTime" TIMESTAMP,
"___createdBy" REFERENCE,
"___etag" STRING,
"___modTime" TIMESTAMP,
"___modifiedBy" REFERENCE,
"___recordID" REFERENCE QUERYABLE,
description STRING,
pageCount INT64,
publishedOn TIMESTAMP,
reviewStatus INT64,
// A single-line comment, for humans
title STRING QUERYABLE,
GRANT WRITE TO "_creator",
GRANT CREATE TO "_icloud",
GRANT READ TO "_world"
);
キーポイント:
DEFINE SCHEMACloudKit スキーマ宣言を開始します。RECORD TYPE Bookという名前のファイルを定義しますBookレコードタイプ。"___createTime"、"___createdBy"、"___etag"、"___modTime"、"___modifiedBy"、"___recordID"CloudKit によってレコード タイプごとに作成されるシステム フィールドです。description、pageCount、publishedOn、reviewStatus、titleアプリケーションのカスタムフィールドです。TIMESTAMP、REFERENCE、STRING、INT64フィールドのデータ型です。QUERYABLE例では、フィールドのクエリ可能なインデックスを作成します。___recordIDそしてtitleインデックスが宣言されています。// A single-line comment, for humansチームが読むためのコメントであり、CloudKit サーバーがファイルを処理するときに無視されます。GRANT WRITE TO "_creator"レコード作成者に書き込みを許可します。GRANT CREATE TO "_icloud"認証された iCloud ユーザーがレコードを作成できるようにします。GRANT READ TO "_world"すべてのユーザーに読み取りを許可します。
本番環境のスキーマ進化ルールを覚えておいてください
(07:14) スキーマ ファイルにより変更が高速化されますが、CloudKit の実稼働環境ルールは変更されていません。レコードタイプは開発環境で追加および削除でき、カスタムフィールドも追加および削除できます。レコード タイプが運用環境に昇格されると、削除したり名前を変更したりすることはできません。運用環境にプロモートされたカスタム フィールドは、削除したり名前を変更したりすることはできません。
Development environment:
- Add and remove record types
- Add and remove custom fields
Production environment:
- Promote new record types
- Add new fields to existing record types
- Cannot delete or rename promoted record types
- Cannot delete or rename promoted custom fields
- Can add and remove indexes
- Can modify security role settings
キーポイント:
- 開発環境はスキーマの迅速な反復に適しています。
- 運用環境では古いレコード タイプとフィールドが保持されるため、CloudKit サーバーは古いバージョンのアプリケーションで使用されているデータを引き続き理解できます。
- 破壊的なスキーマ変更は開発環境に現れる可能性があり、運用環境にプロモートすることはできません。
- インデックスとセキュリティ ロールの設定は、運用環境でも引き続き変更できます。
重要ポイント
-
やるべきこと: 再現可能な統合テスト環境を CloudKit アプリに追加します。 実行する価値がある理由:
cktoolテスト前にスキーマをインポートしてサンプル データを作成し、手動で準備したサーバーの状態に依存するテストを回避できます。 開始方法:reset-schema、import-schema、create-recordXcode スキームのテスト プレアクションを記述し、スキーマ ファイル パスを使用します。$PROJECT_DIR。 -
やるべきこと: CloudKit スキーマを Git コード レビューに組み込みます。 実行する価値がある理由:
.ckdbドキュメントにはレコードの種類、フィールド、インデックス、権限を記述することができ、チームは Swift コードをレビューするのと同じ方法でデータ モデルの変更をレビューできます。 開始方法: 最初に使用しますxcrun cktool export-schema --environment development --output-file schema.ckdb既存のスキーマをエクスポートし、ファイルをプロジェクトに追加します。 -
やるべきこと: UI テスト用の固定クラウド サンプル データを準備します。 実行する価値がある理由:
create-recordJSON を使用したパブリック データベースへの書き込みをサポートし、テストでは同じレコード セットを安定して読み取ることができます。 開始方法: それぞれのテスト シナリオのセットを作成します。--fields-json、テスト終了前スクリプトで必要な CloudKit レコードを 1 つずつ作成します。 -
やるべきこと: チーム用の CloudKit スキーマ移行チェックリストを作成します。 実行する価値がある理由: プロモートされたレコード タイプとカスタム フィールドは、運用環境では削除したり名前を変更したりできません。事前に確認することで導入の失敗を減らすことができます。 開始方法: PR テンプレートに追加します
.ckdb項目を変更し、重大な変更、インデックスの変更、セキュリティ ロールの変更が含まれているかどうかを確認します。 -
対処方法: 継続的統合のために管理トークンとユーザー トークンを分割します。 実行する価値がある理由: 管理トークンはコンテナー構成のみを処理し、ユーザー トークンはデータ書き込みのみを処理し、アクセス許可の境界がより明確になります。 開始方法: まずはこのマシンで使用してください
save-token --type managementそしてsave-token --type user認可が完了すると、テスト スクリプトは構成操作とデータ操作に従ってセグメントに編成されます。
関連セッション
- CloudKit コンソールの紹介 — CloudKit コンソールを使用してデータベースを表示し、スキーマを変更し、コンテナーの変更をデプロイする方法を学びます。
- CloudKit の新機能 — WWDC21 CloudKit の非同期/待機、暗号化フィールド、ゾーン共有について学びます。
- CloudKit と Core Data を通じてデータを共有するアプリを構築する — Core Data と CloudKit の間でデータを共有する実装パスを引き続き学習します。
- Spotlight でアプリ データを表示する — Core Data データが Spotlight 検索インデックスにどのように入力されるかを学びます。
コメント
GitHub Issues · utterances