我目前正在设置 CloudKit 作为 Parse 的替代品,并且需要下载我的所有用户记录。我目前有大约 600 条记录,但我只收到 300 条。
我使用的是名为“User”的自定义记录区域,而不是默认的“Users”记录区域,因为此应用程序仅与一个 appID 绑定(bind)。
我使用的代码基于以下问题的答案,但它对我不起作用。当光标为零时,查询操作似乎不会运行,因为 print(userArray) 从未被调用。预先感谢您的帮助!
CKQuery from private zone returns only first 100 CKRecords from in CloudKit
func queryAllUsers() {
let database = CKContainer.defaultContainer().privateCloudDatabase
let query = CKQuery(recordType: "User", predicate: NSPredicate(value: true))
let queryOperation = CKQueryOperation(query: query)
queryOperation.recordFetchedBlock = self.createUserObject
queryOperation.queryCompletionBlock = { cursor, error in
if cursor != nil {
print("there is more data to fetch")
let newOperation = CKQueryOperation(cursor: cursor!)
newOperation.recordFetchedBlock = self.createUserObject
newOperation.queryCompletionBlock = queryOperation.queryCompletionBlock
database.addOperation(newOperation)
} else {
print(userArray) //Never runs
}
}
database.addOperation(queryOperation)
}
func createUserObject(record: CKRecord) {
let name = record.objectForKey("Name") as! String!
let company = record.objectForKey("Company") as! String!
let dateInductionCompleted = record.objectForKey("DateInductionCompleted") as! NSDate!
var image = UIImage()
let imageAsset = record.objectForKey("Image") as! CKAsset!
if let url = imageAsset.fileURL as NSURL? {
let imageData = NSData(contentsOfURL:url)
let mainQueue = NSOperationQueue.mainQueue()
mainQueue.addOperationWithBlock() {
image = UIImage(data: imageData!)!
userArray.append(User(name: name, company: company, image: image, dateInductionCompleted: dateInductionCompleted))
}
}
print(userArray.count)
}
更新
问题已得到解答,这可能是使用游标进行大型查询时的固有错误。该代码现在通过使用递归函数来工作,工作代码如下:
func queryRecords() {
let database = CKContainer.defaultContainer().privateCloudDatabase
let query = CKQuery(recordType: "User", predicate: NSPredicate(value: true))
let queryOperation = CKQueryOperation(query: query)
queryOperation.qualityOfService = .UserInitiated
queryOperation.recordFetchedBlock = populateUserArray
queryOperation.queryCompletionBlock = { cursor, error in
if cursor != nil {
print("There is more data to fetch")
self.fetchRecords(cursor!)
}
}
database.addOperation(queryOperation)
}
func fetchRecords(cursor: CKQueryCursor?) {
let database = CKContainer.defaultContainer().privateCloudDatabase
let queryOperation = CKQueryOperation(cursor: cursor!)
queryOperation.qualityOfService = .UserInitiated
queryOperation.recordFetchedBlock = populateUserArray
queryOperation.queryCompletionBlock = { cursor, error in
if cursor != nil {
print("More data to fetch")
self.fetchRecords(cursor!)
} else {
print(userArray)
}
}
database.addOperation(queryOperation)
}
func populateUserArray(record: CKRecord) {
let name = record.objectForKey("Name") as! String!
let company = record.objectForKey("Company") as! String!
let dateInductionCompleted = record.objectForKey("DateInductionCompleted") as! NSDate!
var image = UIImage()
let imageAsset = record.objectForKey("Image") as! CKAsset!
if let url = imageAsset.fileURL as NSURL? {
let imageData = NSData(contentsOfURL:url)
let mainQueue = NSOperationQueue.mainQueue()
mainQueue.addOperationWithBlock() {
image = UIImage(data: imageData!)!
userArray.append(User(name: name, company: company, image: image, dateInductionCompleted: dateInductionCompleted))
}
}
print(userArray.count)
}
最佳答案
您可以尝试设置:
queryOperation.qualityOfService = .UserInitiated
这将表明您的用户交互需要数据。 否则可能会发生请求被完全忽略的情况。
正如下面所讨论的,实际的答案是您不应该重复使用完成 block 。相反,您应该创建一个递归函数来从游标中获取下一条记录。可以在以下位置找到该示例:EVCloudKitDao
关于swift - CloudKit 查询操作仅返回 300 个结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35553375/