Swift - 从 Cloudkit 公共数据库中获取所有记录
Posted
技术标签:
【中文标题】Swift - 从 Cloudkit 公共数据库中获取所有记录【英文标题】:Swift - Get all records from Cloudkit Public Database 【发布时间】:2018-11-24 12:15:24 【问题描述】:您好,我正在尝试从 cloudkit 中的 publicDB 中获取所有记录,目前有超过 2000 条记录。我怎样才能将它们全部取出并将它们放入一个数组中? 我试过这两种方法都没有成功。你能帮帮我吗?
1 方法
let predicate = NSPredicate(value: true)
let query = CKQuery(recordType: "Position", predicate: predicate)
query.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
publicDB.perform(query, inZoneWith: nil) (results, error) -> Void in
if error != nil
DispatchQueue.main.async(execute: () -> Void in
self.delegate?.errorUpdating(error: error! as NSError)
return
)
else
self.positionArray.removeAll(keepingCapacity: true)
for record in results!
let position = Position(record: record as CKRecord, database: self.publicDB)
self.positionArray.append(position)
DispatchQueue.main.async(execute: () -> Void in
/* my elaboration with the complete result */
)
2 方法
let predicate = NSPredicate(value: true)
let query = CKQuery(recordType: "Position", predicate: predicate)
query.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
let qop = CKQueryOperation(query: query)
qop.resultsLimit = 3000
qop.recordFetchedBlock = (record: CKRecord) in
let position = Position(record: record, database: self.publicDB)
self.positionArray.append(position)
print(self.positionArray.count)
qop.queryCompletionBlock = (cursor: CKQueryOperation.Cursor?, error: Error?) in
DispatchQueue.main.async(execute: () -> Void in
if let cursor = cursor
print("entro")
let newOperation = CKQueryOperation(cursor: cursor)
newOperation.recordFetchedBlock = qop.recordFetchedBlock
newOperation.queryCompletionBlock = qop.queryCompletionBlock
self.publicDB.add(newOperation)
else if let error = error
print("Error:", error)
// No error and no cursor means the operation was successful
else
print("Finished with records:", self.positionArray)
if(!all)
// my elaboration
else
// my elaboration
)
self.publicDB.add(qop)
使用第一种方法,我最多可以获取 100 条记录。 使用第二种方法,我最多可以获取 400 条记录。 但是我需要用所有超过 2000 条记录填充我的数组,如何才能达到结果?
【问题讨论】:
【参考方案1】:请试试这个!
var Whistle = [CKRecord] ()
func loadWhistles(completionHandler: (() -> Void)?)
let pred = NSPredicate(value: true)
let sort = NSSortDescriptor(key: nomeDaTabela, ascending: ordemDaTabela)
let query = CKQuery(recordType: "Cliente", predicate: pred)
query.sortDescriptors = [sort]
let operation = CKQueryOperation(query: query)
operation.desiredKeys = ["Name"]
operation.resultsLimit = 2000
var newWhistles = Whistle
operation.recordFetchedBlock = record in
newWhistles.append(record)
operation.queryCompletionBlock = [unowned self] (cursor, error) in
DispatchQueue.main.async
if error == nil
//ViewController.isDirty = false
self.clienteRecords = newWhistles
self.clientesTableView.reloadData()
else
let ac = UIAlertController(title: "Fetch failed", message: "There was a problem fetching the list of whistles; please try again: \(error!.localizedDescription)", preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "OK", style: .default))
self.present(ac, animated: true)
PublicDatabase.add(operation)
completionHandler?()
【讨论】:
【参考方案2】:确实存在每次 fetch 操作的限制为 400 条记录,因此您需要检查 查询完成块返回的 CKQueryCursor
值,如果不是 nil
则用它开始另一个操作CKQueryOperation(cursor: cursor)
.
所以原则上你的第二种方法是正确的。我的猜测是您的问题是由于线程问题引起的,请尝试删除DispatchQueue.main.async(execute: () -> Void in
。
附:看看它是如何在RxCloudKit
中完成的(它会自动处理大数据提取),它绝对适用于提取 1000 多条记录 - RecordFetcher.queryCompletionBlock(cursor: CKQueryCursor?, error: Error?)
【讨论】:
以上是关于Swift - 从 Cloudkit 公共数据库中获取所有记录的主要内容,如果未能解决你的问题,请参考以下文章
CloudKit 无法从公共容器中获取数据。错误 1/4000
如何使用 CloudKit 将条目从公共数据库保存到私有数据库