Page tried to end immersive session initiated by a different page

In a SwiftUI VisionOS app that opens with one .plain window and another .volumetric window, I want to automatically close the Volume when the user closes the plain window. Attempting to do so with

ContentView().onDisappear{ dismissWindow(id: kVolumeId) }

results in

Page tried to end immersive session initiated by a different page

I have not found that error documented anywhere. Any advice?

Accepted Reply

Hi @avitzur ,

You can use ScenePhase to check if you've closed ContentView and dismiss the volumetric window there.

For example:

@Environment(\.scenePhase) var scenePhase
...
WindowGroup {
   ContentView()
}
.onChange(of: scenePhase) { _, new in
            switch new {
            case .background: dismissWindow(id: "volumetricWindow")
            case .active: print("active")
            case .inactive: print("inactive")
            @unknown default:
                print("default")
            }
        }

Replies

Hi @avitzur ,

You can use ScenePhase to check if you've closed ContentView and dismiss the volumetric window there.

For example:

@Environment(\.scenePhase) var scenePhase
...
WindowGroup {
   ContentView()
}
.onChange(of: scenePhase) { _, new in
            switch new {
            case .background: dismissWindow(id: "volumetricWindow")
            case .active: print("active")
            case .inactive: print("inactive")
            @unknown default:
                print("default")
            }
        }

Using the scenePhase value is the right approach for this task. Keep in mind that scenePhase depends on where you read this property from. Checkout the documentation for some great examples.

You can close the window when the scenePhase environment variable in the root view of your window becomes .background. For instance, in the Hello World code sample, if I wanted the closing of the main Modules view to close out the Globe volumetric window I could add the following to the Modules view:

.onChange(of: scenePhase, initial: false) { oldValue, newValue in
    if newValue == .background {
        dismissWindow(id: Module.globe.name)
    }
}