CloudKit查询操作仅返回300个结果

时间:2016-02-22 12:14:40

标签: swift cloudkit

我目前正在设置CloudKit作为Parse的替代品,需要下载我的所有用户记录。我目前有大约600条记录,但我只收到300条记录。

我正在使用名为" User"的自定义记录区域。而不是默认"用户"记录区域,因为此应用程序只会绑定到一个appID。

我使用的代码是基于以下问题的答案,但它不适用于我。当光标为nil时,似乎查询操作不会运行,因为从不调用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)
}

1 个答案:

答案 0 :(得分:3)

你可以尝试设置:

queryOperation.qualityOfService = .UserInitiated

这表示您的用户交互需要数据。 否则,可能会发生de request被完全忽略。

如下所述,实际答案是您不应该重复使用完成块。相反,您应该创建一个递归函数来从游标中获取下一个记录。可在以下位置找到相关示例:EVCloudKitDao