我对如何处理复杂的 Swift 数据类型、它们对变量的赋值以及访问其中的值有点困惑。希望有人可以澄清以下内容:
在尝试从 SwiftUI 和 CloudKit 获取数据时,并且在尝试重写 CK 函数以符合 async/await 时,我有以下代码行:
let result = try await container.privateCloudDatabase.records(matching: query)
现在这一行应该从云私有数据库中获取与指定查询匹配的所有记录并返回一些 CKRecords
旧功能如下:
container.privateCloudDatabase.perform(query, inZoneWith: nil) { (rec, err) in
for record in rec {
print("Found this record: \(record)")
}
}
这很好用,因为perform(_:inZoneWith:)
会返回一个 CKRecord 和一个错误,它们在(rec, err) in
语句中被“挑选出来”并传递到循环中进行迭代。
使用新的 async/await 方法,我试图简单地等待并为找到的所有记录分配一个变量,然后迭代返回的数据,挑选出 CKRecords 并执行我想要的任何任务。
我感到困惑的是,当我尝试从返回的结果中挑选数据时,我会以多种方式得到错误。我不完全理解如何描述返回值的数据结构,我认为这是问题的根本原因。
我尝试了一些事情并收到以下错误消息:
如果我尝试:
let (result, err) = try await container.privateCloudDatabase.records(matching: query)
当我使用(尝试将 CKRecords 附加到我之前创建的 CKRecords 数组中)时:
for record in result {
self.myCKRecordArray.append(record)
}
错误消息特别指出:
Cannot convert value of type 'Dictionary<CKRecord.ID, Result<CKRecord, Error>>.Element' (aka '(key: CKRecord.ID, value: Result<CKRecord, Error>)') to expected argument type 'CKRecord'
这肯定给了我一些线索。我相信我的result
变量包含 Dictionary<CKRecord.ID, Result<CKRecord, Error>>.Element 或键/值对列表,其中 CKRecord.ID 是 Result<CKRecord, Error> 值的键。
这很令人困惑..所以如果我理解正确,那么:
for thisDict in result {
let (realResult, err) = result[thisDict.key]
print("Found this record: \(realResult)")
}
理论上应该导致分配给realResult的每个CKRecord的输出,对吗?我只是得到错误:Type of expression is ambiguous without more context
我尝试将其更改为valueForKey
并为其提供更多上下文,但错误消息没有任何变化:
let (realResult, err) = result(valueForKey:thisDict.key) as Result<CKRecord, Error>
我只是相信我不完全理解如何Dictionary<CKRecord.ID, Result<CKRecord, Error>>.Element
从一个由 a:数据结构表示的东西正确访问 CKRecord 。
非常感谢任何对理解的洞察力。
谢谢
更新
好的,根据@Shadowrun 的回答,如果我理解正确的话:
结果来自:
let result = try await container.privateCloudDatabase.records(matching: query)
是一个元组类型。这意味着它有两个元素,第一个是数据字典,第二个是 queryCursor。
如果我想遍历元组的 Dictionary 部分并取出 CKRecord:
for rec in result.0 {
self.myCKRecordArray.append(try rec.value.get())
}
这不会给我任何错误..我理解正确吗?
第二次更新 它确实以这种方式按预期工作。