Views with custom nonisolated init fail to compile when using @MainActor-isolated @Environment properties (e.g., \.openURL, \.dismiss).
From the Swift 6 migration documentation, it seems encouraged to define inits nonisolated, and it seems base SwiftUI components also have their inits defined as nonisolated (e.g. TimelineView, LazyHStack, etc), which makes sense.
How do you achieve marking a SwiftUI View's init as nonisolated when it uses environment variables, without producing the following build error "Main actor-isolated default value of 'self.openURL' cannot be used in a nonisolated initalizer" ?
It seems @State variable defined in a view has the ability to be set in a nonisolated init but not @Environment. What mechanism prevents this under the hood ?
Great question! In SwiftUI, we have made it as easy as possible to use it in the Swift 6 language mode. You should not need to define your custom Views initializers as nonisolated, because the expectation is that they will be initialized from the parent view's isolation context, and View protocol is @MainActor in SwiftUI. This means that there is really no reason for your view to be initialized from a nonisolated context, since the context will be main-actor-isolated anyway.
Great observation that SwiftUI's own custom Views have their initializer marked as nonisolated. This is a pattern that lets us have more flexibility internally in the framework, but in terms of API, we rely on the fact that these views will be automatically isolated to the @MainActor when used in View.body. While this is a pattern we use internally, it is not needed to replicate for your own custom components.
I hope this answers your question! If not, we'd love to see the sample code where it is tricky to avoid marking View.init as nonisolated.
Thank you!