Sample CodevisionOSReviewed 2026-07-21View on Apple Developer

Transforming entities between RealityKit coordinate spaces

At a glance

Item Summary
Purpose Move an entity between a volumetric window and an immersive space using coordinate space transformations.
App architecture CoordSpaceTransformApp owns AppModel; volumetric and immersive views share entities and demonstrate explicit transform conversion between SwiftUI, RealityKit scene, and local coordinate spaces.
Main patterns SwiftUI scene composition, UI–RealityKit bridge, Observable state owner, Explicit coordinate conversion
Project style Code-rich sample with 5 scanned Swift file(s) and 619 implementation line(s).

Project structure

Source bundle/
└── CoordSpaceTransform/
    ├── AppModel.swift  # ImmersiveSpaceState, AppModel
    ├── VolumetricView.swift  # VolumetricView
    ├── ImmersiveView.swift  # ImmersiveView
    ├── CoordSpaceTransformApp.swift  # CoordSpaceTransformApp
    └── ToggleImmersiveSpaceButton.swift  # ToggleImmersiveSpaceButton

Structure observations

  • The runtime boundary is WindowGroup + volumetric window + ImmersiveSpace; the tree is pruned to lifecycle, state, framework, rendering, and ECS files.
  • The source is Swift; role-named types and feature folders separate the major responsibilities.

Overall architecture

Reference code

CoordSpaceTransform/CoordSpaceTransformApp.swift:12 — executable or app-lifecycle anchor.

struct CoordSpaceTransformApp: App {
    // ...
}

The diagram is a responsibility flow, not a claim that every adjacent node directly calls the next. It separates lifecycle, presentation, stable state, framework/session work, and the RealityKit entity graph.

Ownership and state

Ownership evidence

CoordSpaceTransform/CoordSpaceTransformApp.swift:14 — representative stored state or nearest verified lifecycle anchor.

    @State private var appModel = AppModel()
    
    /// The action that dismisses an immersive space.
    @Environment(\.dismissImmersiveSpace) private var dismissImmersiveSpace

    /// The action that presents an immersive space.
    @Environment(\.openImmersiveSpace) private var openImmersiveSpace
Owner Object or state Relationship Mutation authority
CoordSpaceTransformApp AppModel as appModel creates and retains The declaring type controls writes
AppModel Entity as volumeCubeLastSceneTransformEntity creates and retains The owning type coordinates writes
AppModel Entity as volumeRootEntity creates and retains The owning type coordinates writes
AppModel Entity as immersiveSpaceRootEntity creates and retains The owning type coordinates writes

Ownership is intentionally narrow: environment, bindings, observed objects, weak links, and delegate callbacks do not prove lifetime ownership. Initialized stored services and wrapper-managed state do; entities added inside a RealityKit content closure belong to that entity graph.

Class and protocol design

Type Responsibility Depends on or conforms to
CoordSpaceTransformApp (CoordSpaceTransform/CoordSpaceTransformApp.swift:12) Declares app lifecycle and top-level dependency lifetime. App
VolumetricView (CoordSpaceTransform/VolumetricView.swift:12) Presents UI and forwards gestures or lifecycle events. View
AppModel (CoordSpaceTransform/AppModel.swift:20) Owns feature state and domain transitions. Concrete framework collaborators
ImmersiveView (CoordSpaceTransform/ImmersiveView.swift:12) Presents UI and forwards gestures or lifecycle events. View

The reviewed source defines no local substitution protocol. Its App, View, delegate, renderer, ARKit, and RealityKit conformances are framework-facing contracts, so this document does not label the whole app protocol-oriented.

Access control

Symbol Access Verified effect Likely rationale
@State private var appModel = AppModel() (CoordSpaceTransform/CoordSpaceTransformApp.swift:14) private Use stays inside the declaration and same-file extensions permitted by Swift. Inference: Hide lifecycle-sensitive state or an implementation step.

No reviewed Swift access example uses fileprivate, private(set), public, open; declarations without a modifier are internal.

Reference code

CoordSpaceTransform/CoordSpaceTransformApp.swift:14 — representative visibility boundary.

@main
struct CoordSpaceTransformApp: App {
    // ...
    @State private var appModel = AppModel()
    // ...
}

Logic ownership and placement

Logic Owning type or file Placement rationale
Application/command lifecycle CoordSpaceTransformApp The executable boundary determines app, controller, scene, or command lifetime.
Presentation and user intent VolumetricView The view/controller forwards input and owns only presentation-local work.
Shared feature state and commands AppModel A stable owner prevents view recomputation or callbacks from duplicating transitions.

Design patterns

Pattern Source evidence Purpose or tradeoff
SwiftUI scene composition CoordSpaceTransform/CoordSpaceTransformApp.swift:12 Keeps windows, volumes, and immersive presentation visible at the app boundary.
UI–RealityKit bridge CoordSpaceTransform/VolumetricView.swift:23 Builds or hosts the RealityKit entity graph from SwiftUI or a platform view/controller lifecycle.
Observable state owner CoordSpaceTransform/AppModel.swift:20 Keeps shared feature state in a stable owner rather than in transient view values.
Explicit coordinate conversion CoordSpaceTransform/AppModel.swift:67 Makes source and destination spaces explicit instead of treating transforms as globally interchangeable.

Naming conventions

  • Role suffixes are evidence, not decoration: App: CoordSpaceTransformApp; Model: AppModel; View: ImmersiveView, VolumetricView.
  • Protocols: no app-defined protocol in the reviewed source.
  • Commands use verb-led methods: updateTransformsWhileDragging, updateTransform, moveCubeFromImmersiveSpaceToVolumetricWindow, getDurationBasedOnDistance, makeCubeSubEntityOfVolumeRoot, createContentAndPositionAttachments, createCube, createVolumetricWindowCube.
  • Files and folders use primary-type or responsibility names such as Views, Models, Rendering, Components, Systems, Packages, or feature names where those boundaries exist.

Architecture takeaways

  • Treat CoordSpaceTransformApp as the owner of executable or scene lifecycle, not automatically as the owner of every entity created later.
  • Keep view/controller input near presentation, but move sessions, reconstruction, capture, rendering, shared game state, or documents into stable owners when their lifetime exceeds one callback or render pass.

Source map

Source file Relevant symbols
CoordSpaceTransform/AppModel.swift:11 ImmersiveSpaceState, AppModel
CoordSpaceTransform/VolumetricView.swift:12 VolumetricView
CoordSpaceTransform/ImmersiveView.swift:12 ImmersiveView
CoordSpaceTransform/CoordSpaceTransformApp.swift:12 CoordSpaceTransformApp
CoordSpaceTransform/ToggleImmersiveSpaceButton.swift:10 ToggleImmersiveSpaceButton