Swift async
functions can only directly be called from other async
functions. In synchronous code, the only mechanism provided by the Swift Concurrency model to create asynchronous work is detach
. The detach
operation creates a new, detached task that is completely independent of the code that initiated the detach
: the closure executes concurrently, is independent of any actor unless it explicitly opts into an actor, and does not inherit certain information (such as priority).
Detached tasks are important and have their place, but they don't map well to cases where the natural "flow" of control is from the synchronous function into async code, e.g., when reacting to an event triggered in a UI:
@MainActor func saveResults() {