首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法在for循环中从公共数据库中提取多个CKReference记录

无法在for循环中从公共数据库中提取多个CKReference记录
EN

Stack Overflow用户
提问于 2020-07-27 11:29:58
回答 1查看 35关注 0票数 0

我有一个具有许多位置CKRecords的联系人CKRecord (一对多关系),联系人CKRecord和位置CKRecord都是在公共数据库中创建的。我通过location上名为owningContact的字段将联系人的CKReference添加到locaiotn中。

代码语言:javascript
复制
ckRecord["owningContact"] = CKReference(record: contactRecord!, action: .deleteSelf)

我转到cloudKit仪表板并验证这两条记录是否都存在。location CKRecord具有字段owningContact,该字段包含联系人CKRecord的recordName。我定义了一个函数来获取如下位置:

代码语言:javascript
复制
private func iCloudFetchLocations(withContactCKRecord: CKRecord, completionHandler: @escaping ([CKRecord]?, Error?) -> Void) {
     var records = [CKRecord]()

    let recordToMatch = CKReference(recordID: withContactCKRecord.recordID, action: .deleteSelf)
    let predicate = NSPredicate(format: "owningContact == %@", recordToMatch)
    
    // Create the query object.
    let query = CKQuery(recordType: "location", predicate: predicate)
    let queryOp = CKQueryOperation(query: query)
    queryOp.resultsLimit = 1
    queryOp.qualityOfService = .userInteractive
    queryOp.recordFetchedBlock = {
        records.append($0)
        print($0)
    }
    queryOp.queryCompletionBlock = { (cursor, error) in
        guard error == nil else {
            if let ckerror = error as? CKError {
                
                self.aErrorHandler.handleCkError(ckerror: ckerror)
            }
            return
        }
        if (cursor != nil) {
            let newOperation = CKQueryOperation(cursor: cursor!)
            newOperation.resultsLimit = queryOp.resultsLimit
            newOperation.recordFetchedBlock = queryOp.recordFetchedBlock
            newOperation.queryCompletionBlock = queryOp.queryCompletionBlock
        
            self.publicDB?.add(newOperation)
        }
        completionHandler(records, error)
    }
    self.publicDB?.add(queryOp)
}

然后,我调用代码来根据联系人CKRecord获取位置CKRecord,如下所示:

代码语言:javascript
复制
 let predicate = NSPredicate(format: "TRUEPREDICATE")
    let query = CKQuery(recordType: Cloud.Entity.Contact, predicate: predicate)
    publicDB?.perform(query, inZoneWith: nil, completionHandler: { (records, error) in
        guard error == nil else {
            if let ckerror = error as? CKError {
                self.aErrorHandler.handleCkError(ckerror: ckerror)
            }
            return
            completion(false)
        }
        if let contactRecords = records {
            for aContactRecord in contactRecords {
                // fetch Location Data
                self.iCloudFetchLocations(withContactCKRecord: aContactRecord, completionHandler: { records, error in
                    guard error == nil else {
                        if let ckerror = error as? CKError {
                            self.aErrorHandler.handleCkError(ckerror: ckerror)
                        }
                        return
                            completion(false)
                    }
                    
                    if let locationRecords = records {
              }
         })
     }
  }
 })

我有两个联系人,第一个联系人已被CKReferenc‘s引用到该位置,而第二个联系人仍未被CKReferenc’s引用到该位置。我认为这就是问题所在:第一次在循环中,contact CKRecord信息是通过调用iCloudFetchLocations发送的,它立即返回,不等待云响应,for循环发送第二个contact并再次调用iCloudFetchLocations。由于第二个联系人没有指向该位置的CKReference,因此呼叫失败,并且我永远无法到达第一个联系人的位置,因为它还没有返回。

如何解决这个问题?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-07-28 06:14:14

我发现我没有将Queryable字段: owningContact设置为CKReference。我发现打印错误的方式是这样的:

代码语言:javascript
复制
 if let ckerror = error as? CKError {
            print(ckerror.userInfo)
            print(ckerror.errorUserInfo)
            self.aErrorHandler.handleCkError(ckerror: ckerror)
  }

一旦我这样做了,它就开始工作了,因为我在一个for循环中,我想它在之前的fetch上超时了。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63108296

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档