我正在使用 CloudKit(默认的公共数据库)来存储有关两支球队之间比赛的信息。我正在尝试使用带有 async/await 的 Swift Concurrent 方法来检索比赛和团队数据。
比赛被存储为带有一些元数据的“Match” RecordType,比如比赛的年份(“matchYear”)。“比赛”记录类型还包含一个名为“团队”的记录类型的参考列表(每场比赛两个团队)。团队名称存储在“团队”记录类型中(字段“团队名称”)
我的 CloudKit 架构的粗略描述
“Match” Record Type
Fields:
matchYear: Int64
teams: Reference (List)
…
“Team” Record Type
Fields:
teamName: String
…
使用以下代码,我可以从 CloudKit 读取所有“匹配”记录,并将该列表存储到 MatchRecords 数组中,然后我可以使用它来显示匹配列表(使用 SwiftUI,如果这有什么不同的话)。结果数组还包含对每场比赛的球队的引用。
struct MatchRecord {
var recordID: CKRecord.ID
var matchYear: Int
var teams: [CKRecord.Reference]
…
}
…
private lazy var container = CKContainer.default()
private lazy var database = container.publicCloudDatabase
…
@MainActor func loadMatchList() async throws -> [MatchRecord] {
let predicate = NSPredicate(value: true)
let sortDescriptors = [NSSortDescriptor(key: “matchYear", ascending: false),NSSortDescriptor(key: "___createTime", ascending: false)]
let query = CKQuery(recordType: “Match”, predicate: predicate)
query.sortDescriptors = sortDescriptors
let (matchResults, _) = try await database.records(matching: query)
let allMatches: [MatchRecord] = matchResults
.compactMap { _, result in try? result.get() }
.compactMap {
let match = MatchRecord(
recordID: $0.recordID,
matchYear: $0[“matchYear"] as! Int,
teams: $0["teams"] as! [CKRecord.Reference])
// Potentially team record retrieval goes here…
return match
}
return allMatches
}
作为此异步功能的一部分,我如何检索团队记录,以便我也将获得可用于列表视图的团队名称?
(我可能首先获取匹配列表,然后遍历该数组并检索每个匹配的详细数据,但这似乎很浪费。我猜应该有一种方法可以将它插入到代码示例中标记的 compactMap 闭包中上面,但是我的 map/reduce 和 async/await 技能让我失望了……)
数据结构可能如下所述。
struct MatchRecord {
var recordID: CKRecord.ID
var matchYear: Int
var teams: [TeamRecord]
…
}
struct TeamRecord {
var recordID: CKRecord.ID
var teamName: String
…
}
FWIW我知道因为每场比赛只有两支球队,我也可以将球队名称存储为比赛记录的一部分,但将来我计划还包括每支球队的名单信息,所以我需要来用一种干净且可扩展的方法从 CloudKit 中检索这种类型的分层数据……</p>
在这里,将 CoreData 与 CloudKit 一起使用不是一个选项。