Considering the following code
@main
struct so_tcaMultipleIndepententWindowsOnMacOSApp: App {
var body: some Scene {
WindowGroup {
ContentViewVanilla()
}
}
}
struct ContentViewVanilla: View {
@State private var id = UUID()
var body: some View {
Text(id.uuidString)
}
}
according to Apple's documentation on WindowGroup
, opening a new window on macOS should open windows that are independent from each other:
Every window in the group maintains independent state. For example, the system allocates new storage for any State or StateObject variables instantiated by the scene’s view hierarchy for each window that it creates.
So, I'd expect the UUID
differ in every window I open when running the app–which is not the case. As it is, each new window displays the same UUID
.
I am on Xcode 15.1 running on macOS 14.2.
What am I missing?
edit: working with a StateObject
works as expected, working with @State
still does not
When I refactor above code to use a ViewModel that holds the UUID
, it works as I would expect:
@main
struct so_tcaMultipleIndepententWindowsOnMacOSApp: App {
var body: some Scene {
WindowGroup {
ContentViewVanilla()
}
}
}
struct ContentViewVanilla: View {
@StateObject private var viewModel = ViewModel()
var body: some View {
Text(viewModel.id.uuidString)
}
}
class ViewModel: ObservableObject {
let id = UUID()
}
I do understand that there's a difference in using a reference type rather than a value type, but given the information in Apple's documentation (see above), I would hope that I would not need to have to create a separate class here.
The reason I do not want to do this is that I want to use TCA which is based on struct
and not on class
.
As per Sweeper's comment below, it seems that for Xcode 15.0 and macOS 14.1.1 my first approach is totally creating independent windows, so there is still some hope that this is a bug in Apple's stack that I perhaps should file a feedback for.
Any further thoughts on this?
Even though I am not agreeing with the documentation that tells me to expect separate Windows for
@State
(cause it does not for me, even not for the macOS 13 I tried it with, using a virtual machine installation), I found a workaround I can live with right now.The workaround is wrapping the TCA structs I want to use in an
@ObservableObject
like so:I will next incorporate this into my real TCA project and see if there are any issues with this approach down the TCA layer–I don't expect any, but than again I was hoping not to need anything like this workaround neither…