Use of Async in sync? And their differences?

Using semaphore to force to wait for the Task completion is very risky and I wouldn't use it in the production code.

There is a great blog post about this topic in detail Swift Concurrency Waits for No One

Stick to other well-known tools for that.

For the Button action case. Personally I prefer to push as long a possible up the chain the need of spinning unstructured Task. In this case I would rather make a view model with the async function and spin a task from the View

Button {
    Task {
        await viewModel.buttonTapped()
    }
}

If you need to prevent the re-entrancy you might handle it either by making a guard in
viewModel (e.g. checking the state or by keeping a reference to a task)

You might also create a custom AsyncButton reusable component that would have built-in reentrancy prevention + async actions support.

I agree that SwiftUI didn't encounter proper adoption of Swift Concurrency (besides the task modifier), leading to many (sometimes improper) solutions to the lack of handling async/await by default.

Testing unstructured Task is also a non-trivial topic

3 Likes