What’s the proper way to use actors and @Observable classes when building services and view models?

Generated on 7/30/2024

1 search

To properly use actors and @Observable classes when building services and view models, you should follow these guidelines:

  1. Use Actors for Concurrency Safety: Actors in Swift are reference types that automatically protect their state by serializing accesses. This ensures that only a single task can execute at a time on an actor, which helps prevent data races. For example, if you have a UserStore that needs to be accessed from different concurrency domains, making it an actor will synchronize accesses and eliminate concurrency issues (A Swift Tour: Explore Swift’s features and design).

  2. Main Actor for UI-Related Code: When dealing with UI-related code, such as views and models, you should run them on the main actor. This ensures that all UI updates are performed on the main thread, which is crucial for maintaining a responsive user interface. For instance, in the Coffee Tracker app, views and models were set to run on the main actor, while background operations were performed on dedicated actors (Migrate your app to Swift 6).

  3. Isolate Methods Appropriately: If you have methods that need to run on a specific actor, you can declare them as non-isolated or use the assume isolated method to inform the compiler about the concurrency context. This is useful for callbacks that need to run on the main actor but are called from different concurrency contexts (Migrate your app to Swift 6).

  4. Use Value Types for Communication: When passing data between actors, use value types to avoid shared mutable state. This helps prevent data races. For example, in the Coffee Tracker app, the Drink type was a struct with immutable properties, making it safe to pass between actors (Migrate your app to Swift 6).

  5. Annotations for Main Actor Isolation: Many delegates and protocols, especially those related to SwiftUI, are annotated to operate only on the main actor. This reduces the need for explicit main actor annotations in your code. For instance, the SwiftUI view protocol is implicitly isolated to the main actor by default (What’s new in SwiftUI).

By following these guidelines, you can effectively manage concurrency in your Swift applications, ensuring that your services and view models are both safe and performant. For more detailed information, you can refer to the sessions "Migrate your app to Swift 6" and "A Swift Tour: Explore Swift’s features and design" from WWDC 2024.