[英]batch fetching with cloudkit ckqueryoperation
Is it possible to implement 'batch fetching' in cloudkit, so that i can call a method to pull the next X records?是否可以在 cloudkit 中实现“批量提取”,以便我可以调用一种方法来提取下一条 X 记录? Currently, according to CloudKit Batch Fetches?
目前,根据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.
cloudkit 隐式地处理这个问题,但我想以某种方式创建一个方法,允许我每次提取指定数量的查询。 Heres what I have so far: (where continuePullPosts is a similar method to the one i posted)
这是我到目前为止所拥有的:(其中 continuePullPosts 与我发布的方法类似)
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.您应该使用您想要的值而不是
CKQueryOperationMaximumResults
常量值设置结果限制。
My recomendation is define a completion handler with parameters for the CKRecord
results and the CKQueryCursor
.我的建议是定义一个完成处理程序,其中
CKRecord
结果和CKQueryCursor
。 This completion handler must be invoked in the queryCompletionBlock
handler of your CKQueryOperation.必须在
queryCompletionBlock
处理程序中调用此完成处理程序。
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.调用此函数后,您可以将闭包中返回的游标保存在变量中,如果它不是 nil,则再次调用该函数以恢复接下来的 10 条记录。
So @Adolfo's answer got me 95% of the way, but I had one issue:所以@Adolfo 的回答让我成功了 95%,但我遇到了一个问题:
Every time I would reach the last page (or batch) or data, it just started sending me data from the beginning of my data set.每次我到达最后一页(或批次)或数据时,它都会从数据集的开头开始向我发送数据。
This was a problem because after I ran out of data, I wanted the loading to stop.这是一个问题,因为在我用完数据后,我希望停止加载。
To fix this, I added an argument to specify if it was the first fetch or not.为了解决这个问题,我添加了一个参数来指定它是否是第一次提取。 This allowed me to only create a new query when it was the first fetch.
这允许我只在第一次获取时创建一个新查询。 If it wasn't the first fetch, no new query would be made and an empty array would be returned.
如果它不是第一次获取,则不会进行新查询并返回一个空数组。
public func fetchYourRecords(isFirstFetch: Bool, _ cursor: CKQueryCursor? = nil, completionHandler handler: @escaping YourFetchCompletionHandler) -> Void {
var result: [CKRecord] = [CKRecord]()
let queryOP: CKQueryOperation
if isFirstFetch {
// Create the operation for the first time
queryOP = CKQueryCursor(query:...)
} else if let cursor = cursor {
// Operation to fetch another 10 records.
queryOP = CKQueryOperation(cursor: cursor)
} else {
// If not first time and if cursor is nil (which means
// there is no more data) then return empty array
// or whatever you want
handler([], nil)
return
}
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)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.