Sendable conforming with @Observable macros

Using the class below:

@Observable
final class AppState: Sendable {
	enum Stage: Sendable {
		case authorizationRequired
		case authorized
	}
	
	static var shared = AppState()
	var currentStage: AppState.Stage
	// Warning: Stored property '_currentStage' of 'Sendable'-conforming class 'AppState' is mutable

	// … other code
}

I get the following warning:

Applying the @MainActor doesn't resolve the issue. Documentation said:

Contain only stored properties that are immutable and sendable

I do understand what the warning says, but I need the mutability.
I have read a similar topic, but I don't understand what I need to do ?

5 Likes

Oddly, I'm experiencing the opposite. I have

@Observable
final class Foo: Sendable {
    static let shared = Foo()
    var bar: Bool? = nil
}

And I expected the concurrency warning but I am not seeing it. The concurrency warning "Stored property 'bar' of 'Sendable'-conforming class 'Foo' is mutable; this is an error in the Swift 6 language mode" only appears when I remove @Observable.

I'm surprised that Observable would "fix" it, and I'm suspicious as to whether actually does. But I'm having a hard time finding useful information about it.

Btw, in your example I would at least make the reference to the static shared var into static let.

I figured out why @Observable hid the warning. It's because now the warning applies to the code generated by the macro, and won't appear until that code is generated/run.

You can mark the entire class as MainActor and remove the Sendable conformance. Adding MainActor isolation makes it implicitly Sendable.