Presentations are not currently supported in Volumetric contexts

I'm getting this error in the debugger ("Presentations are not currently supported in Volumetric contexts.") in VisionOS when I try to present an alert in a Volume. What's the correct way to present a modal alert in a volumetric window group? I'm using Xcode 15.3 Beta 3 with Apple Vision Pro (1.1) simulator.

This is also preventing me from using the RevenueCat paywall UI since it also returns this error.

var body: some Scene {
    WindowGroup {
        SheilaAppView()
            .presentPaywallIfNeeded(
                requiredEntitlementIdentifier: "access",
                purchaseCompleted: { customerInfo in
                    print("Purchase completed: \(customerInfo.entitlements)")
                },
                restoreCompleted: { customerInfo in
                    // Paywall will be dismissed automatically if "pro" is now active.
                    print("Purchases restored: \(customerInfo.entitlements)")
                }
            )
    }.windowStyle(.volumetric)
}
Answered by Vision Pro Engineer in 782108022

Presentations are supported from a WindowGroup with a windowStyle of .plain or .automatic. Consider adding a UI affordance to your volumetric window that creates a non-volumetric WindowGroup to present your additional UI.

ImmersiveAlertApp.swift

struct ImmersivePresentationApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        
        WindowGroup(id: "nonVolumetricWindow") {
            SomeView()
                .padding()
        }
        .windowResizability(.contentSize)

        ImmersiveSpace(id: "ImmersiveSpace") {
            ImmersiveView()
        }
    }
}

ImmersiveView.swift

struct ImmersiveView: View {
    @Environment(\.openWindow) var openWindow
    let buttonAttachmentId = "button"
    
    var body: some View {
        RealityView { content, attachments  in
            if let buttonAttachment = attachments.entity(for: buttonAttachmentId) {
                buttonAttachment.position = [0, 1.3, -1.0]
                content.add(buttonAttachment)
            }
        }
        attachments: {
            Attachment(id: buttonAttachmentId){
                Button("Open non-volumetric window"){
                    openWindow(id: "nonVolumetricWindow")
                }
                .glassBackgroundEffect()
            }
        }
    }
}

SomeView.swift

struct SomeView: View {
    @State private var showAlert = false
    var body: some View {
        VStack {
            Text("Look a non-volumetric window.")
            Button("Show alert") {
                showAlert = true
            }
            .alert(isPresented: $showAlert) {
                Alert(
                    title: Text("Lorem ipsum dolor"),
                    message: Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.")
                )
            }
        }
    }
}

Presentations are supported from a WindowGroup with a windowStyle of .plain or .automatic. Consider adding a UI affordance to your volumetric window that creates a non-volumetric WindowGroup to present your additional UI.

ImmersiveAlertApp.swift

struct ImmersivePresentationApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        
        WindowGroup(id: "nonVolumetricWindow") {
            SomeView()
                .padding()
        }
        .windowResizability(.contentSize)

        ImmersiveSpace(id: "ImmersiveSpace") {
            ImmersiveView()
        }
    }
}

ImmersiveView.swift

struct ImmersiveView: View {
    @Environment(\.openWindow) var openWindow
    let buttonAttachmentId = "button"
    
    var body: some View {
        RealityView { content, attachments  in
            if let buttonAttachment = attachments.entity(for: buttonAttachmentId) {
                buttonAttachment.position = [0, 1.3, -1.0]
                content.add(buttonAttachment)
            }
        }
        attachments: {
            Attachment(id: buttonAttachmentId){
                Button("Open non-volumetric window"){
                    openWindow(id: "nonVolumetricWindow")
                }
                .glassBackgroundEffect()
            }
        }
    }
}

SomeView.swift

struct SomeView: View {
    @State private var showAlert = false
    var body: some View {
        VStack {
            Text("Look a non-volumetric window.")
            Button("Show alert") {
                showAlert = true
            }
            .alert(isPresented: $showAlert) {
                Alert(
                    title: Text("Lorem ipsum dolor"),
                    message: Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor.")
                )
            }
        }
    }
}

Thanks. It's a shame that Apple's documentation doesn't call out this limitation. I was hoping it was a bug. :)

It's strange and inconsistent that requesting permissions can display alerts from volumetric contexts just fine but displaying a purchase screen (or rating prompt) isn't possible without a window. I hope this is improved upon in the future so we don't have to break immersion with windows!

This is an issue when for example showing an immersive space that has system SwiftUI entities which can present view, like for example a password textfield with a keyboard which has a "Passwords" button, that button will try to present the Passwords UI and therefore triggering this error

Presentations are not currently supported in Volumetric contexts
 
 
Q