Hey,
I've stumbled over an error that I don't quite understand. It is in the context of SwiftUI, but it's also something related to actor-isolation in general, so I thought I'd asked here first.
So, I have this simple setup of a property wrapper that's accessing a SwiftUI EnvironmentObject
(thanks to DynamicProperty
):
@MainActor
final class SomeObject: ObservableObject {}
@MainActor @propertyWrapper
struct TestWrapper: DynamicProperty {
@EnvironmentObject private var someObject: SomeObject
var wrappedValue: Int?
init(wrappedValue: Int? = nil) {
self.wrappedValue = wrappedValue ?? 42
}
}
struct ContentView: View {
var body: some View {
Text("Hello, world!")
}
}
#Preview {
// Error: Call to main actor-isolated initializer 'init(wrappedValue:)' in a synchronous nonisolated context
@Previewable @TestWrapper var test
ContentView()
.environmentObject(SomeObject())
}
When I try to add this property wrapper inside of a #Preview
macro, I get an error:
Error: Call to main actor-isolated initializer 'init(wrappedValue:)' in a synchronous nonisolated context
Everything is fine, however, if I explicitly set the value to nil
:
// Compiles fine
@Previewable @TestWrapper var test = nil
I'm curious. Is this some SwiftUI/Preview-macro magic that's having issues here or is it some kind of synthetic initializer that's being used when not explicitly setting the value to nil
?
This entire issue only appears whenever I use a main actor-isolated environment object inside the property wrapper and then constrain the property wrapper itself to be on the main actor as well.
Thanks!
Edit: I just realized that this couldn't even work in practice There is no way to inject the environment object into the property wrapper in that preview. But nonetheless, I'd like to understand the error