Do the official docs talk somewhere about CloudKit consistency? According to my tests it appears to be eventually consistent – reading a record immediately after writing it might work and might not (returning empty results):
CKDatabase *database = [[CKContainer defaultContainer] publicCloudDatabase];
CKRecord *record = [[CKRecord alloc] initWithRecordType:@"Foo"];
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
[database saveRecord:record completionHandler:^(CKRecord *record, NSError *error) {
CKQuery *query = [[CKQuery alloc] initWithRecordType:@"Foo" predicate:[NSPredicate predicateWithFormat:@"TRUEPREDICATE"]];
[database performQuery:query inZoneWithID:nil completionHandler:^(NSArray *results, NSError *error) {
XCTAssertEqualObjects(results, @[], @"Freshly written object not returned by query."); // succeeds
dispatch_semaphore_signal(semaphore);
}];
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
Is there a way to force a strongly consistent read that would reflect all previous updates?
It's a little of both: CloudKit is strongly consistent if you fetch a record by identifier, but eventually consistent when you fetch a record with a query.
When a CKModifyRecordsOperation returns successfully the record is immediately fetchable by its identifier.
However, it takes some time for the server to scan the record's values and update and distribute its search indexes. Until that indexing completes you won't see the record in any queries.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With