1

This is a method I call to fetch public records:

private func fetchPublicRecordZonesChanges(completion: ErrorHandler?) {
    let zone = CKRecordZone.default()
    let options = CKFetchRecordZoneChangesOptions()
    options.previousServerChangeToken = nil

    var records = [CKRecord]()
    var recordIDsToDelete = [CKRecordID]()
    let operation = CKFetchRecordZoneChangesOperation(recordZoneIDs: [zone.zoneID], optionsByRecordZoneID: [zone.zoneID: options])
    operation.database = CloudAssistant.shared.publicDatabase
    operation.recordChangedBlock = { record in
        records.append(record)
    }

    operation.recordWithIDWasDeletedBlock = { recordID, string in
        recordIDsToDelete.append(recordID)
    }

    operation.recordZoneChangeTokensUpdatedBlock = { _, token, _ in
        if let token = token {
            Token.temporaryPublicZoneServerChangeToken = token
        }
    }

    operation.recordZoneFetchCompletionBlock = { [weak self] _, token, _, _, error in
        if let error = error, error.isTokenExpiredError {
            UserDefaults.remove(forKey: PublicZoneServerChangeTokenKey)
            self?.fetchPublicRecordZonesChanges(completion: completion)
            return
        }
        if let token = token {
            Token.temporaryPublicZoneServerChangeToken = token
        }
    }

    operation.fetchRecordZoneChangesCompletionBlock = { [weak self] error in
        self?.save(records: records, recordIDsToDelete: recordIDsToDelete) { error in
            completion?(error)
        }
    }
    operationQueue.addOperation(operation)
}

But nothing is fetched although that method is called, additionally not even once recordChangedBlock closure is called. Why?

I am pretty sure I have a records there:

enter image description here

and environment is also very fine, because private development records are fetched correctly (using of course different method). What am I doing wrong?

3
  • 1
    CKFetchRecordZoneChangesOperation can only be used with private or shared databases, not the public database. Commented Aug 14, 2018 at 5:42
  • 1
    Wow, thank you;) I didnt know that. What can I use to fetch all changes from public database? Commented Aug 14, 2018 at 5:43
  • are you serious only Private DB or shred DB?!? i just wasted days trying to find a way to fetch changes for public DB Commented Mar 8, 2021 at 2:02

1 Answer 1

2

To be notified of changes to your Public database, create a CKQuerySubscription for the record type(s) you care about. Here's an example:

let subscription = CKQuerySubscription(
  recordType: "Question", 
  predicate: NSPredicate(value: true), 
  subscriptionID: "subscriptionQuestion", 
  options: [
    .firesOnRecordCreation, 
    .firesOnRecordUpdate, 
    .firesOnRecordDeletion
  ])

let info = CKNotificationInfo()
info.shouldSendContentAvailable = true
subscription.notificationInfo = info

let operation = CKModifySubscriptionsOperation(subscriptionsToSave: [subscription], subscriptionIDsToDelete: nil)

operation.modifySubscriptionsCompletionBlock = { saved, deleted, error in
  if let error = error{
    print("Add subscription error: \(error)")
  }else{
    print("Successfully added Question subscription.")
  }
}

//:::
let container = CKContainer(identifier: "...")
container.publicCloudDatabase.add(operation)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.