【发布时间】:2021-09-02 06:18:06
【问题描述】:
对于如何处理复杂的 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
这很令人困惑..所以如果我理解正确,那么:
for thisDict in result {
let (realResult, err) = result[thisDict.key]
print("Found this record: \(realResult)")
}
理论上应该把每个CKRecord的输出分配给realResult吧?我只是得到错误: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 数据结构表示的东西正确访问 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())
}
这不会给我任何错误..我理解正确吗?
第二次更新 它确实以这种方式按预期工作。
【问题讨论】: