AboutExperienceProjectsWriting

Advanced Swift: Taming State with Actors and Structured Concurrency

For years, dealing with concurrency in iOS meant battling DispatchQueue, escaping closures, and the dreaded callback hell. With the introduction of Structured Concurrency (async/await) and Actors in Swift, the paradigm has fundamentally shifted.

The Problem with Data Races

In highly concurrent applications—like a real-time POS system—multiple threads often need to read and write to the same state simultaneously. Using serial queues or locks to prevent data races was verbose and error-prone. One missed lock, and you had a crash in production that was impossible to reproduce.

Enter Actors

Actors in Swift are reference types that isolate their state from the rest of the program. They guarantee mutually exclusive access to their internal state.

By wrapping our critical state managers in an actor, the Swift compiler statically ensures that no data races can occur. If a background thread attempts to read the actor’s state, the compiler forces you to use await, ensuring the access is safely queued.

Structured Concurrency

Combining Actors with TaskGroup allows us to fire off multiple network requests (e.g., fetching inventory, processing a transaction) in parallel and await their collective result cleanly, without a single DispatchGroup or completion handler in sight. This drastically reduces the cognitive load required to read and maintain the code.