CKError:查询过滤器超出了值限制:容器

时间:2017-07-27 09:26:52

标签: ios swift cloudkit ckqueryoperation

我想拉下500"访问"来自公共数据库的记录。 CloudKit一次只能为您提供100条记录,因此我只需使用下面的CKQueryCursor来获取我想要的所有记录。

func fetchVisits(_ cursor: CKQueryCursor? = nil) {
    print("fetchVisits \(cursor)")
    var operation: CKQueryOperation!
    if let cursor = cursor {
        operation = CKQueryOperation(cursor: cursor)
    } else {
        let query = CKQuery(recordType: "Visit", predicate: NSPredicate(format: "Client IN %@ AND ANY Students IN %@", visitClients, visitStudents))
        operation = CKQueryOperation(query: query)
    }
    operation.recordFetchedBlock = {
        (record) in
        totalVisits.append(record)
    }
    operation.queryCompletionBlock = {
        (cursor, error) in
        if let error = error {
            //handle error
        } else if let cursor = cursor {
            self.fetchVisits(cursor)
        } else {
            //all done!
        }
    }
    CKContainer.default().publicCloudDatabase.add(operation)
}

我将这个函数称为:

fetchVisits()

这很好,它可以获得我需要的所有访问。控制台日志

fetchVisits nil
fetchVisits Optional(<CKQueryCursor: 0x174228140; id=4bb7887c326fc719, zone=(null)>)
fetchVisits Optional(<CKQueryCursor: 0x17422a320; id=f67fb25669486da9, zone=(null)>)
fetchVisits Optional(<CKQueryCursor: 0x174228380; id=7e87eb8b7cfe1a74, zone=(null)>)
fetchVisits Optional(<CKQueryCursor: 0x17422cc80; id=e77e47ef2b29c8a4, zone=(null)>)

但问题是现在我想按下按钮时刷新,现在它给了我这个错误:

&#34;服务不可用&#34; (二千〇二十二分之六); &#34;请求失败,http状态代码为503&#34 ;; 30.0秒后重试

这是非常自我解释的,我想我通过请求一个可怜的500条记录来压倒服务器?所以我等了30秒再次调用该函数,现在我收到了这个错误。

&#34;限制超出&#34; (二千〇二十三分之二十七); server message =&#34;查询过滤器超出了值限制:容器为250

出于某种原因,我无法再次运行该功能。如果我重新启动应用程序它再次正常工作,但只是第一次。此问题似乎特定于任何返回CKQueryCursor的表。我有其他表格,我只有少于100条记录(因此光标为零)我可以多次拉出这些表格而没有任何问题。

3 个答案:

答案 0 :(得分:4)

好的,我之前已经看过这个问题,我相信这个问题是CloudKit服务器上的一个错误。根据我的经验,它与复杂的查询有关。

如果您尝试将谓词更改为:

NSPredicate(value: true)

甚至通过删除任何部分来简化现有部分,这可能足以解决它。

答案 1 :(得分:1)

在查询操作完成之前,您需要向iCloud请求更多CKRecords。

...
operation.queryCompletionBlock = {
    (cursor, error) in
    if let error = error {
        //handle error
    } else if let cursor = cursor {
        self.fetchVisits(cursor)
    } else {
        //all done!
    }
}
...

函数self.fetchVisits(cursor)调用在完成块内完成,这意味着您在当前操作完成之前请求更多记录。

可能的解决方案是使用一个闭包(completionHandler),其中包含CKQueryCursor,当用户需要更多记录(滚动表或其他)时,再次调用一个self.fetchVisits传递闭包上收到的cursos。 / p>

答案 2 :(得分:0)

docs说:

  

服务器可以随时更改其限制,但以下是   一般准则:

     
      每个操作
  • 400个项目(记录或共享)
  •   
  • 每个请求2 MB(不计算资产大小)
  •   
     

如果您的应用收到CKError.Code.limitExceeded,则它必须拆分   进行一半操作,然后再次尝试两个请求