With your query object ready to go, you’ll need to use a CloudKit database to perform it.
This is a companion discussion topic for the original entry at https://www.raywenderlich.com/27184225-cloudkit/lessons/6
With your query object ready to go, you’ll need to use a CloudKit database to perform it.
In this episode you use a withThrowingTaskGroup
but the usage seems odd to me. You haven’t actually performed your async task in the addTask
method, so I’m not sure what the value was there. I understand the need for the task group itself, but you’ve not taken advantage of the functionality of the parallel tasks. Seem like it should be something more like this:
return try await withThrowingTaskGroup(of: Establishment?.self) { group in
records.forEach { record in
group.addTask {
try? await Establishment(record: record, database: database)
}
}
return try await group
.compactMap { $0 }
.reduce(into: []) { $0.append($1) }
}
Me neither. It was months ago that I recorded this, and I don’t remember what I was thinking. Apologies to all viewers; we’ll improve this in the next course update.
At this point, I’ve found there to be quite a lot of common generic async operations lacking in the standard library—in this case, a compactMap
overload that does what your code does (and preserves order, as that’s generally desired). I might rewrite it this way:
establishments = try await database.records(matching: query).matchResults
.compactMap { try await Establishment(record: $1.get(), database: database) }
public extension Sequence {
func map<Transformed>(
priority: TaskPriority? = nil,
_ transform: @escaping (Element) async throws -> Transformed
) async rethrows -> [Transformed] {
try await withThrowingTaskGroup(
of: EnumeratedSequence<[Transformed]>.Element.self
) { group in
for (offset, element) in enumerated() {
group.addTask(priority: priority) {
(offset, try await transform(element))
}
}
return try await group.reduce(
into: map { _ in nil } as [Transformed?]
) {
$0[$1.offset] = $1.element
} as! [Transformed]
}
}
func compactMap<Transformed>(
priority: TaskPriority? = nil,
_ transform: @escaping (Element) async throws -> Transformed?
) async rethrows -> [Transformed] {
try await map(transform).compactMap { $0 }
}
}