了解使用新的 async/await API 获取 CKRecords 的结果

Lka*_*abo 6 ios swift cloudkit ios15

我对如何处理复杂的 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)")
    }
}
Run Code Online (Sandbox Code Playgroud)

这非常有效,因为perform(_:inZoneWith:)会返回一个 CKRecord 和一个错误,它们在语句中被“分开”(rec, err) in并传递到循环中进行迭代。

使用新的 async/await 方法,我尝试简单地等待并将变量分配给找到的所有记录,然后迭代返回的数据,挑选 CKRecords 并执行我想要的任何任务。

我感到困惑的是,当我尝试以多种方式从返回的结果中挑选数据时,我只是收到错误。我不完全理解如何描述返回值的数据结构,我认为这是问题的根本原因。

我尝试了一些方法并收到以下错误消息:

如果我尝试:

let (result, err)  = try await container.privateCloudDatabase.records(matching: query)
Run Code Online (Sandbox Code Playgroud)

当我使用时(尝试将 CKRecords 附加到我之前创建的 CKRecords 数组中):

for record in result {
   self.myCKRecordArray.append(record)
}
Run Code Online (Sandbox Code Playgroud)

错误消息具体指出:

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)")
        }
Run Code Online (Sandbox Code Playgroud)

理论上应该将每个CKRecord的输出分配给realResult,对吗?我刚刚收到错误:Type of expression is ambiguous without more context

我尝试将其更改为valueForKey并为其提供更多上下文,但错误消息没有变化:

let (realResult, err) = result(valueForKey:thisDict.key) as Result<CKRecord, Error>
Run Code Online (Sandbox Code Playgroud)

我只是相信我不完全理解如何从以下数据结构表示的内容中正确访问 CKRecord Dictionary<CKRecord.ID, Result<CKRecord, Error>>.Element

任何对理解的见解都将受到高度赞赏。

谢谢

更新

好的,根据@Shadowrun 的回答,如果我理解正确的话:

结果来自:

let result  = try await container.privateCloudDatabase.records(matching: query)
Run Code Online (Sandbox Code Playgroud)

是一个元组类型。这意味着它有两个元素,第一个是数据字典,第二个是查询游标。

如果我想迭代元组的字典部分并获取 CKRecord:

        for rec in result.0 {
            self.myCKRecordArray.append(try rec.value.get())
        }
Run Code Online (Sandbox Code Playgroud)

这不会给我任何错误..我理解正确吗?

第二次更新 它确实按预期工作。

Sha*_*run 3

返回 a 的函数与返回或抛出 的Result<T, E>函数之间存在\xe2\x80\x99 的等价关系。返回元组的函数也有类似的等价TE(T?, E?)

\n

当将具有完成处理程序的函数映射到异步函数时,它们会变成抛出函数,因此应该是:

\n
let result = try await container\xe2\x80\xa6.\n
Run Code Online (Sandbox Code Playgroud)\n

错误(如果有)将被抛出

\n