Is it possible to implement 'batch fetching' in cloudkit, so that i can call a method to pull the next X records? Currently, according to CloudKit Batch Fetches? cloudkit handles this implicitly, but I would like to somehow create a method that allows me to pull a specified number of queries each time. Heres what I have so far: (where continuePullPosts is a similar method to the one i posted)
queryOP.recordFetchedBlock = { record in
//do stuff here
annotations.append(postToAdd)
}
queryOP.queryCompletionBlock = { [unowned self] (cursor, error) in
DispatchQueue.main.async {
if error == nil {
if completionHandler(annotations) {
if cursor != nil {
let newQueryOP = CKQueryOperation(cursor: cursor!)
self.continuePullPosts(curLocation: curLocation, queryOP: newQueryOP,
annotations: annotations, completionHandler: completionHandler)
}
}
} else {
print(error)
print("could not pull posts")
}
}
}
queryOP.resultsLimit = CKQueryOperationMaximumResults
CKContainer.default().publicCloudDatabase.add(queryOP)
}
You should set the result limit with your desired value instead of CKQueryOperationMaximumResults
constant value.
My recomendation is define a completion handler with parameters for the CKRecord
results and the CKQueryCursor
. This completion handler must be invoked in the queryCompletionBlock
handler of your CKQueryOperation.
Once your handler is invoked you can process the results, and if the cursor is not null means that there are more results to fetch.
It could be something like that
// Completion Handler (closure) definition
public typealias YourFetchCompletionHandler = (_ records: [CKRecords]?, cursor: CKQueryCursor?) -> (Void)
And here the function where you fetch records
public func fetchYourRecords(_ cursor: CKQueryCursor? = nil, completionHandler handler: @escaping YourFetchCompletionHandler) -> Void
{
var result: [CKRecord] = [CKRecord]()
let queryOP: CKQueryOperation
if let cursor = cursor
{
// Operation to fetch another 10 records.
queryOP = CKQueryOperation(cursor: cursor)
}
else
{
// Create the operation for the first time
queryOP = CKQueryCursor(query:...)
}
queryOp.recordFetchedBlock = { (record: CKRecord) -> Void in
result.append(record)
}
queryOP.queryCompletionBlock = { [unowned self] (cursor, error) in
handler(result, cursor)
}
// Fetch only 10 records
queryOP.resultsLimit = 10
CKContainer.default().publicCloudDatabase.add(queryOP)
}
Once you invoke this function you can save the cursor returned in the closure in a variable, if it's not nil, to call once again the function to recover the next 10 records.