我有一个具有许多位置CKRecords的联系人CKRecord(一对多关系) 联系人CKRecord和位置CKRecord均在公共数据库中创建。我通过在位置上名为owneringContact的字段将来回CKReference添加到locaiotn。
ckRecord["owningContact"] = CKReference(record: contactRecord!,action: .deleteSelf)
我转到cloudKit仪表板并验证两个记录均存在。位置CKRecord具有字段owneringContact,该字段拥有联系人CKRecord的recordName。我定义了一个函数来获取这样的位置:
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,如下所示:
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'ed到该位置,而第二个联系人仍未被CKReferenc'ed到该位置。 我认为这是问题所在:第一次在循环联系中,通过调用iCloudFetchLocations发送CKRecord信息,该信息立即返回而无需等待云响应,并且for循环发送第二个联系并再次调用iCloudFetchLocations。由于第二个联系人没有该位置的CKReference,因此通话失败,而且我还无法到达第一个联系人的位置,因为它尚未返回。
该如何解决?