TechnologiesSwiftUI

OpenImmersiveSpaceAction struct

iOSmacOStvOSwatchOSvisionOS✓ renders

An action that presents an immersive space.

How it works

OpenImmersiveSpaceAction presents an immersive space on visionOS, transitioning your app from a bounded window into the surrounding environment. You don't construct it yourself; SwiftUI provides a ready-made instance through the environment, and you call it like a function to request that a scene declared with ImmersiveSpace become active. Reach for it whenever a control in your interface should take the wearer out of the shared space and into your own fully or mixed immersive content, such as a galaxy, a room, or a guided experience.

  1. Read the action from the environment with @Environment(\.openImmersiveSpace)

    The action is delivered as an environment value rather than created directly, so SwiftUI can wire it to the active scene phase and platform. Bind it to a property using the openImmersiveSpace key path, as in @Environment(\.openImmersiveSpace) private var openImmersiveSpace, and that property becomes a callable handle to the action for the rest of the view.

  2. Call the action and identify the space with the id parameter

    Invoke the value like a function, passing the identifier you assigned to the corresponding ImmersiveSpace scene so SwiftUI knows which one to present. Here openImmersiveSpace(id: "Galaxy") requests the space registered under "Galaxy"; the action also offers overloads that accept a value to pass into a data-driven space.

  3. Await the call inside a Task because it's asynchronous

    Opening an immersive space is an async operation, so the call must be awaited from an asynchronous context. The example wraps it in a Task { let result = await openImmersiveSpace(id: "Galaxy") } launched from the Button action, which keeps the synchronous body responsive while the system performs the transition.

  4. Branch on the returned OpenImmersiveSpaceAction.Result

    The call resolves to a Result value reporting how the request finished, so you can update state accordingly. The switch result handles .opened when the space becomes active, .userCancelled when the wearer dismisses the request, and .error when presentation fails, with @unknown default covering future cases — each arm here assigns a message to status.

  5. Trigger it from a control, only one space at a time

    Because the action is just a callable handle, it slots naturally into any control's action closure, such as the Button("Open Immersive Space") shown here. Note that a single immersive space is open at a time, so calling the action while one is already presented has no effect — dismiss the current space first.

Try it — Change openImmersiveSpace(id: "Galaxy") to an id that no scene declares and watch the result fall through to .error, setting status to "Failed to open".

Example & preview

Press Run live & edit to compile it in your browser — then edit the Swift on the left and the preview re-renders live.

OpenImmersiveSpaceAction.swift
struct OpenImmersiveSpaceActionDemo: View {
    @Environment(\.openImmersiveSpace) private var openImmersiveSpace
    @State private var status = "Tap to enter immersion"

    var body: some View {
        VStack(spacing: 16) {
            Image(systemName: "visionpro")
                .font(.largeTitle)
            Text(status)
                .font(.headline)
            Button("Open Immersive Space") {
                Task {
                    let result = await openImmersiveSpace(id: "Galaxy")
                    switch result {
                    case .opened: status = "Immersive space opened"
                    case .userCancelled: status = "User cancelled"
                    case .error: status = "Failed to open"
                    @unknown default: status = "Unknown"
                    }
                }
            }
            .buttonStyle(.borderedProminent)
        }
        .padding()
    }
}
Live preview
Tap to enter immersion Open Immersive Space
Tap to enter immersion Open Immersive Space
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →