I'm trying to download a batch of records from my iCloud public database using CloudKit and the cursor. The code works fine for the first 3 executions, regardless of how the resultsLimit is set, but the 4th completion block is never executed. If resultsLimit is not set I get 300 records, if it's set to 50 I get 150, if it's set to 5 I get 15...
No error is reported and the block appears to be added but is never executed. Platform is OS X. Here's the code in question:
let queryOp = CKQueryOperation(query: query)
queryOp.recordFetchedBlock = self.fetchedDetailRecord
queryOp.resultsLimit = 5
queryOp.queryCompletionBlock = { [weak self]
(cursor: CKQueryCursor!, error: NSError!) -> Void in
println("comp block called with \(cursor) \(error)")
if error != nil {
println("Error on fetch \(error.userInfo)")
} else {
if cursor != nil {
let nextOp = CKQueryOperation(cursor: cursor)
nextOp.recordFetchedBlock = self!.fetchedDetailRecord
nextOp.queryCompletionBlock = queryOp.queryCompletionBlock
nextOp.resultsLimit = 5
self!.publicDatabase?.addOperation(nextOp)
println("added next fetch")
} else {
self!.fileHandle!.closeFile()
self!.exportProgressIndicator.stopAnimation(self)
}
}
}
self.publicDatabase?.addOperation(queryOp)
And here's the results from the console -
459013587628.012 0 459013587628.621 1 459013587628.863 2 459013587629.113 3 459013587629.339 4 comp block called with nil added next fetch 459013587828.552 5 459013587828.954 6 459013587829.198 7 459013587829.421 8 459013587829.611 9 comp block called with nil added next fetch 459013587997.084 10 459013587997.479 11 459013587997.74 12 459013587997.98 13 459013587998.207 14
The big number is just the time between calls to the recordFetchedBlock with the second number being the count of times that block has been called.
I'm stumped...any ideas on how to proceed? Oh, container and publicDatabase are class variables and initialized prior to running the code snippet above.
The way you're defining nextOp inside of your queryCompletionBlock scope is causing a problem after three iterations of that block. If you break the creation of the CKQueryOperation out into its own method your problem goes away.
Here is the code:
func fetchedDetailRecord(record: CKRecord!) -> Void {
println("Retrieved record: \(record)")
}
func createQueryOperation(cursor: CKQueryCursor? = nil) -> CKQueryOperation {
var operation:CKQueryOperation
if (cursor != nil) {
operation = CKQueryOperation(cursor: cursor!)
} else {
operation = CKQueryOperation(query: CKQuery(...))
}
operation.recordFetchedBlock = self.fetchedDetailRecord
operation.resultsLimit = 5
operation.queryCompletionBlock = { [weak self]
(cursor: CKQueryCursor!, error: NSError!) -> Void in
println("comp block called with \(cursor) \(error)")
if error != nil {
println("Error on fetch \(error.userInfo)")
} else {
if cursor != nil {
self!.publicDatabase?.addOperation(self!.createQueryOperation(cursor: cursor))
println("added next fetch")
} else {
self!.fileHandle!.closeFile()
self!.exportProgressIndicator.stopAnimation(self)
}
}
}
return operation
}
func doQuery() {
println("Querying records...")
self.publicDatabase?.addOperation(createQueryOperation())
}
This could be another approach (already updated to Swift 3).
It does not stops after third iteration, but continues until the end
var queryOp = CKQueryOperation(query: query)
queryOp.recordFetchedBlock = self.fetchedARecord
queryOp.resultsLimit = 5
queryOp.queryCompletionBlock = { [weak self] (cursor : CKQueryCursor?, error : Error?) -> Void in
print("comp block called with \(cursor) \(error)")
if cursor != nil {
let nextOp = CKQueryOperation(cursor: cursor!)
nextOp.recordFetchedBlock = self!.fetchedARecord
nextOp.queryCompletionBlock = queryOp.queryCompletionBlock
nextOp.resultsLimit = queryOp.resultsLimit
//this is VERY important
queryOp = nextOp
self!.publicDB.add(queryOp)
print("added next fetch")
}
}
self.publicDB.add(queryOp)
I successfully use it to retrieve hundreds of records from CloudKit
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