他の多くの人が抱えているように、CKDatabaseSubscription で同じ問題が発生しました。
問題を説明する場合に備えて、最初にいくつかの警告をリストします。
- サブスクリプションは多くの場合、「Developer」CloudKit ダッシュボードに表示されません (それらは存在しますが、表示されません。テストする最も簡単な方法は、サブスクリプションの名前を変更し、CloudKit がサブスクリプションの重複について文句を言うかどうかを確認することです)。
- プッシュ通知が Simulator に送信されない
解決:
これを修正したのは、カスタム プライベート ゾーンを作成し、すべてのデータをそのゾーンに保存することでした (プライベート データベースでのみ機能します)。次に、そのゾーンへの変更に関するプッシュ通知を受け取ります。
ゾーンを作成する必要があります (CKAccountStatus = .available の確認後、およびレコードの保存前)。
let operation = CKModifyRecordZonesOperation(recordZonesToSave: [CKRecordZone(zoneName: "MyCustomZone")], recordZoneIDsToDelete: nil)
operation.modifyRecordZonesCompletionBlock = { (savedRecordZones: [CKRecordZone]?, deletedRecordZoneIDs: [CKRecordZoneID]?, error: Error?) in
if let error = error {
print("Error creating record zone \(error.localizedDescription)")
}
}
privateDatabase?.add(operation)
そして、レコードを保存するときにそのゾーンを使用します:
let record = CKRecord(recordType: "MyRecordType", zoneID: CKRecordZone(zoneName: "MyCustomZone"))
// you can save zone to CKRecordID instead, if you want a custom id
次に、CKFetchDatabaseChangesOperation をスキップし (ゾーンは既にわかっているため)、代わりに CKFetchRecordZoneChangesOptions を使用します。
let options = CKFetchRecordZoneChangesOptions()
options.previousServerChangeToken = myCachedChangeToken
let operation = CKFetchRecordZoneChangesOperation(
recordZoneIDs: [myCustomZoneId],
optionsByRecordZoneID: [myCustomZoneId: options]
)
operation.fetchAllChanges = true
operation.recordChangedBlock = { (record: CKRecord) -> Void in
... do something
}
operation.recordWithIDWasDeletedBlock = { (recordId: CKRecordID, recordType: String) -> Void in
... do something
}
operation.recordZoneFetchCompletionBlock = { (recordZoneId, changeToken, tokenData, isMoreComing, error) in
if let error = error {
print("Error recordZoneFetchCompletionBlock: \(error.localizedDescription)")
return
}
myCachedChangeToken = changeToken
}
privateDatabase?.add(operation)