Don’t Use Actors For State Data

I wish I had read Paul Hudson’s post, “Important: Do not use an actor for your SwiftUI data models” from last November. It would have saved me hurt from a day wasted trying to get a small data model conforming to @GlobalActor to work with a SwiftUI view.

So, the key point is, do not use an actor for your SwiftUI data models. At least as of now, March 29, 2025. This applies to reading @Published properties of reference types conforming to Observable(Object).

Why? Any code like AstrodynamicState that conforms to Observable(Object) must be @MainActor. Modifying any of AstrodynamicState’s @Published properties must be on the main thread. I am going to assume that reading AstrodynamicState’s published properties will also cause problems. For example,

@globalActor

actor AstrodynamicStateActor: ObservableObject {

    static var shared = AstrodynamicStateActor()

}

@AstrodynamicStateActor
class AstrodynamicState: ObservableObject {

    static let shared = AstrodynamicState()

    @Published var semiMajorAxis: Double = 0.0

    ...

    // Calculate semiMajorAxist in an asyn function...

    ...

}

Then reading this in a SwiftUI View as say, a Text,

struct COEView: View { 

    var body: some View {

       Text(“\(Task { await AstrodynamicState.shaed.semiMajorAxis } as? Double ?? 0.0, specifier: "%.2E") km”)

    }

}

Will not result in the value of AstrodynamicState’s published property semiMajorAxis being displayed, but will instead see “0.00” displayed. Nothing like orbiting the core of the central body.

So, actors are a really bad choice for any data models used with SwiftUI.

Leave a comment