This async let inside the task group child task is very un-necessary and doesn't achieve anything really, just "another" child task that will then be awaited on anyway, and even be cancelled along with parent etc.
It is important however that if the user changes screens that someTask doesn't cancel
That depends how you called this piece of code -- if the outer parent task would get cancelled, all these child tasks would too. If you want to not have child tasks be cancelled, then structured concurrency is really the opposite of what you're trying to do, child tasks do get cancelled.
Having that said, cancellation is cooperative, so I'm not sure you actually need to not cancel the child tasks -- e.g. if you're not gonna act on the cancellation at all, it would not matter if a task got cancelled or not.
I'd wager that this is probably what @bostshakur means with "not caring to wait" for. At least I fail to think of any other possibly useful interpretation in the context of some cleanup operations.
So, I think this would be a valid way to go about it:
Task { // 1
await withDiscardingTaskGroup { group in // 2
for match in allMatches {
group.addTask {
_ = try? await someTask(match) // 3
}
}
}
}
Some more explanation:
The outermost unstructured task ensures the entire thing isn't cancelled if, for example, it is started from a SwiftUI view's .task modifier (as the modifier's task would be cancelled if the view disappears)
Since I guess "not caring" includes potential errors I catch and ignore them way sooner (see point 3), so I can omit the try here. That's just style, since the outermost task isn't awaited anywhere anyway.
This line assumes someTask() does return a result and can throw, but you're not interested in result or error. If it can only throw, the _ = is not needed, obviously. Also, I explicitly ignore thrown errors here with the try?, which, imo, makes it more explicit to the reader than to "bubble up" to withDiscardingTaskGroup (also, I would have to use withThrowingDiscardingTaskGroup then instead). Note, however, that this means that even if a child task in the group does throw, the not yet finished child tasks do not get cancelled and run to completion (whether they throw an error or not). Whether this is what you want depends on the use case. Should a throwing child task require that any outstanding siblings get cancelled, you have to use withThrowingDiscardingTaskGroup and put the try? before that.