CKFetchDatabaseChangesOperation returns no record zone IDs

1.2k views Asked by At

I'm using CloudKit in my app and have begun by following the best practises in the WWDC video"CloudKit Best Practises"

The first thing to do is to check for changes which I do like so,

let changesOperation = CKFetchDatabaseChangesOperation(previousServerChangeToken: databaseChangeToken)
changesOperation.fetchAllChanges = true
changesOperation.recordZoneWithIDChangedBlock = { self.recordZoneWithIDChanged($0) }
changesOperation.recordZoneWithIDWasDeletedBlock = { self.recordZoneWithIDWasDeleted($0) }
changesOperation.changeTokenUpdatedBlock = { self.changeTokenUpdate($0) }
changesOperation.fetchDatabaseChangesCompletionBlock = { self.fetchDatabaseChangesCompletion($0, isMoreComing: $1, error: $2) }

privateDatabase.add(changesOperation)

There are records in the private database that I am setting up the fetch for, but I only ever get the changeTokenUpdatedBlock and the fetchDatabaseChangesCompletion.

Am I right in saying I should expect to see recordZoneWithIDChangedBlock being hit when I run this operation and my private database's default zone to be passed in to this block?

It means when I call my fetchDatabaseChangesCompletion, there's nothing to fetch because the array of record zone IDs is empty: (note, error is nil)

fileprivate func fetchDatabaseChangesCompletion(_ newToken: CKServerChangeToken?, isMoreComing: Bool, error: Error?)
{
    if let error = error
    {
        //  Handle error

        return
    }

    let fetchZoneChangesOperation = CKFetchRecordZoneChangesOperation(recordZoneIDs: changedRecordZoneIDs,
                                                                      optionsByRecordZoneID: nil)
    fetchZoneChangesOperation.recordChangedBlock = { self.recordChanged($0) }
    fetchZoneChangesOperation.recordWithIDWasDeletedBlock = { self.recordWithIDWasDeleted($0, string: $1) }
    fetchZoneChangesOperation.recordZoneFetchCompletionBlock = { self.recordZoneFetchCompletion($0, newChangeToken: $1, clientSentChangeTokenData: $2, isMoreComing: $3, error: $4) }
    fetchZoneChangesOperation.completionBlock = { self.fetchRecordZoneChangesCompletion() }

    privateDatabase.add(fetchZoneChangesOperation)
}
1

There are 1 answers

0
lostAtSeaJoshua On

I ran into this same problem and it is due to CKFetchDatabaseChangesOperation and CKFetchRecordZoneChangesOperation only working on custom zones. CloudKit really wants developers to compartmentalize data so they support more capabilities in custom zones.

The disadvantage of using the default zone for storing records is that it does not have any special capabilities. You cannot save a group of records to iCloud atomically in the default zone. Similarly, you cannot use a CKFetchRecordChangesOperation object on records in the default zone.

CKRecordZone default() Reference

CKFetchRecordChangesOperation was deprecated in iOS 10 and replaced with CKFetchRecordZoneChangesOperation.