I want to pull down around 500 "Visit" records from the public database. CloudKit only gives you 100 records at a time so I just utilize the CKQueryCursor like below to get all the records I want.
func fetchVisits(_ cursor: CKQueryCursor? = nil) {
print("fetchVisits \(cursor)")
var operation: CKQueryOperation!
if let cursor = cursor {
operation = CKQueryOperation(cursor: cursor)
} else {
let query = CKQuery(recordType: "Visit", predicate: NSPredicate(format: "Client IN %@ AND ANY Students IN %@", visitClients, visitStudents))
operation = CKQueryOperation(query: query)
}
operation.recordFetchedBlock = {
(record) in
totalVisits.append(record)
}
operation.queryCompletionBlock = {
(cursor, error) in
if let error = error {
//handle error
} else if let cursor = cursor {
self.fetchVisits(cursor)
} else {
//all done!
}
}
CKContainer.default().publicCloudDatabase.add(operation)
}
I call the function like:
fetchVisits()
That works fine, it gets all the visits I need. Console Log
fetchVisits nil
fetchVisits Optional(<CKQueryCursor: 0x174228140; id=4bb7887c326fc719, zone=(null)>)
fetchVisits Optional(<CKQueryCursor: 0x17422a320; id=f67fb25669486da9, zone=(null)>)
fetchVisits Optional(<CKQueryCursor: 0x174228380; id=7e87eb8b7cfe1a74, zone=(null)>)
fetchVisits Optional(<CKQueryCursor: 0x17422cc80; id=e77e47ef2b29c8a4, zone=(null)>)
But the issue is now I want to refresh when I push a button and now it gives me this error:
"Service Unavailable" (6/2022); "Request failed with http status code 503"; Retry after 30.0 seconds
Which is pretty self explanatory, I guess I am overwhelming the server by requesting a measly 500 records? So I wait 30 seconds and invoke the function again and now I get this error.
"Limit Exceeded" (27/2023); server message = "Query filter exceeds the limit of values: 250 for container
For some reason I cannot run that function again. If I restart the app it works fine again but only the first time. This issue seems to be specific to any table that returns a CKQueryCursor. I have other tables that I'm hitting that have less than 100 records (so the cursor is nil) and I can pull those multiple times without any issues.
Ok, so I've seen this before and the issue is, I believe, a bug in on the CloudKit servers. In my experience, it has to do with complex queries.
If you try changing your predicate to:
NSPredicate(value: true)
Or even simplifying your existing one by removing the ANY part, that may be enough to fix it.