简体   繁体   English

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

[英]CloudKit Query Operation only returns 300 results

I am currently setting up CloudKit as a replacement to Parse and need to download all of my user records. 我目前正在设置CloudKit作为Parse的替代品,需要下载我的所有用户记录。 I currently have around 600 records but I am only receiving 300. 我目前有大约600条记录,但我只收到300条记录。

I'm using a custom record zone called "User" rather than the default "Users" record zone as this app will only ever be tied to one appID. 我正在使用名为“用户”的自定义记录区而不是默认的“用户”记录区域,因为此应用程序只会绑定到一个appID。

The code I am using is based on the answer to the below question but it's not working for me. 我使用的代码是基于以下问题的答案,但它不适合我。 It seems that the query operation does not run when the cursor is nil as the print(userArray) is never called. 当光标为nil时,似乎查询操作不会运行,因为从不调用print(userArray)。 Thanks in advance for your help! 在此先感谢您的帮助!

CKQuery from private zone returns only first 100 CKRecords from in CloudKit 来自私有区域的CKQuery仅返回CloudKit中的前100个CKRecords

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)
}

UPDATE UPDATE

The question has been answered, it was possibly an inherent bug when using a cursor for large queries. 问题已得到解答,当使用游标进行大型查询时,这可能是一个固有的错误。 The code now works by using a recursive function, working code below: 代码现在通过使用递归函数工作,下面的代码如下:

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)
}

Could you try setting: 你可以尝试设置:

queryOperation.qualityOfService = .UserInitiated

This will indicate that your user interaction requires the data. 这表明您的用户交互需要数据。 Otherwise it could happen that de request is ignored completely. 否则可能会完全忽略de request。

As discussed below the actual answer was that you should not re-use completion blocks. 如下所述,实际答案是您不应该重复使用完成块。 Instead you should create a recursive function for fetching the next records from a cursor. 相反,您应该创建一个递归函数来从游标中获取下一个记录。 A sample of that can be found at: EVCloudKitDao 可以在以下位置找到样本: EVCloudKitDao

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM