Sample CodevisionOSReviewed 2026-07-21View on Apple Developer

Enabling video reflections in an immersive environment

At a glance

Item Summary
Purpose Create a more immersive experience by adding video reflections in a custom environment.
App architecture PlayerModel owns playback while ImmersiveEnvironment and its state handler map the selected environment into RealityKit environment-probe blending.
Main patterns SwiftUI scene composition, SwiftUI–RealityKit bridge, Explicit immersive-space lifecycle, Observable state owner, Async update consumer, Environment-probe state adapter
Project style Code-rich sample with 46 scanned Swift file(s) and 4372 Swift line(s); resources and generated assets are excluded from those counts.

Project structure

Source bundle/
├── DestinationVideo/Model/visionOS/ImmersiveEnvironment.swift  # ImmersiveEnvironment, ImmersiveSpaceState
├── DestinationVideo/Model/visionOS/EnvironmentStateHandler.swift  # EnvironmentStateType, EnvironmentStateHandler
├── DestinationVideo/Views/visionOS/ImmersiveEnvironmentView.swift  # ImmersiveEnvironmentView
├── DestinationVideo/DestinationVideo.swift  # DestinationVideo
├── DestinationVideo/ContentView.swift  # ContentView
├── DestinationVideo/Player/PlayerModel.swift  # Presentation, PlayerModel, PlayerViewObserver
├── DestinationVideo/Player/SystemPlayerView.swift  # SystemPlayerView, Coordinator, SystemPlayerView
├── DestinationVideo/SharePlay/WatchingCoordinator.swift  # WatchingCoordinator, PlaybackCoordinatorDelegate
└── Packages/Studio/Package.realitycomposerpro/ProjectData/main.json  # authored RealityKit content

Structure observations

  • The runtime boundary is WindowGroup + ImmersiveSpace; the pruned tree lists only files that explain lifecycle, state, or framework integration.
  • App code is split into role-named views, models, managers, providers, components, or systems.
  • Authored .reality or Reality Composer Pro content is a real implementation boundary; Swift loads or drives it rather than reproducing its entity graph.
  • Uses the Destination Video archive but focuses on the immersive-environment state and RealityKit environment-probe updates that produce reflected video lighting.

Overall architecture

Reference code

DestinationVideo/DestinationVideo.swift:14 — the app or executable entry declares the outer scene lifecycle.

struct DestinationVideo: App {
    // ...
}

The diagram is a responsibility flow, not a claim that every adjacent node directly calls the next. It keeps scene ownership, shared state, RealityKit content, and framework-provider work at separate levels.

Ownership and state

Ownership evidence

DestinationVideo/DestinationVideo.swift:19 — representative stored state or the nearest verified lifecycle anchor.

@main
struct DestinationVideo: App {
    // ...
    @State private var player: PlayerModel
    // ...
}
Owner Object or state Relationship Mutation authority
DestinationVideo PlayerModel as player owns a SwiftUI-managed reference slot Only the declaring scope writes
DestinationVideo ModelContainer as modelContainer stores and coordinates Only the declaring scope writes
ContentView PlayerModel as player receives a shared/non-owning reference The upstream owner controls lifetime; this scope may invoke its mutable API
DestinationVideo ImmersiveEnvironment as immersiveEnvironment creates and retains Only the declaring scope writes

Ownership here is deliberately narrow: @Environment and weak references are shared links, initialized @State or stored services are lifecycle ownership, and a RealityView content closure owns additions to its entity graph without making the SwiftUI view a reference-type owner.

Class and protocol design

Type Responsibility Depends on or conforms to
DestinationVideo (DestinationVideo/DestinationVideo.swift:14) Declares app scenes and top-level dependency lifetime. App
ContentView (DestinationVideo/ContentView.swift:11) Presents UI and forwards gestures or lifecycle events. View
PlayerModel (DestinationVideo/Player/PlayerModel.swift:21) Owns observable feature state and domain transitions. Concrete framework collaborators
Coordinator (DestinationVideo/Player/SystemPlayerView.swift:25) Coordinates long-lived framework or cross-view work. NSObject, AVPlayerViewDelegate
WatchingCoordinator (DestinationVideo/SharePlay/WatchingCoordinator.swift:14) Coordinates long-lived framework or cross-view work. Concrete framework collaborators
PlaybackCoordinatorDelegate (DestinationVideo/SharePlay/WatchingCoordinator.swift:155) Provides a sample-specific value or framework adapter. NSObject, AVPlayerPlaybackCoordinatorDelegate
CategoryListView (DestinationVideo/Views/CategoryListView.swift:11) Presents UI and forwards gestures or lifecycle events. View

The source defines no local substitution protocol in the reviewed boundary. Its protocol use is framework-facing (App, View, RealityKit/ARKit protocols, or platform adapters), so this document does not label the whole app protocol-oriented.

Access control

Symbol Access Verified effect Likely rationale
public private(set) var activeState: EnvironmentStateType = .none (DestinationVideo/Model/visionOS/EnvironmentStateHandler.swift:45) private(set) The getter keeps its wider visibility, while mutation stays inside the declaring type and its permitted same-file extensions. Inference: Protect a state invariant while allowing observation.
@Environment(PlayerModel.self) private var player (DestinationVideo/ContentView.swift:12) private Use is restricted to the declaration and same-file extensions permitted by Swift. Inference: Hide implementation details and lifecycle-sensitive state.
public var lightStateVisualEntity: Entity? { (DestinationVideo/Model/visionOS/EnvironmentStateHandler.swift:110) public The declaration is available to importing modules, subject to its containing type’s visibility. Inference: Satisfy a cross-target or framework-facing surface without implying subclassability.

No reviewed declaration uses fileprivate, open; unmodified Swift declarations are internal.

Reference code

DestinationVideo/Model/visionOS/EnvironmentStateHandler.swift:45 — representative visibility boundary.

    public private(set) var activeState: EnvironmentStateType = .none

    public func gatherEntities(from rootEntity: Entity?) {
        // ...
    }

Logic ownership and placement

Logic Owning type or file Placement rationale
Scene declaration and dependency lifetime DestinationVideo The App/entry boundary determines window, volume, and immersive-space lifetime.
Presentation, attachments, and gestures ContentView SwiftUI view code forwards user intent and RealityView lifecycle events.
Shared feature state and commands PlayerModel A role-named owner prevents sibling views from duplicating transitions.
Playback resource lifecycle DestinationVideo/Player/InlinePlayerView.swift:19 The player/component owner survives view recomputation and drives system presentation.

Design patterns

Pattern Source evidence Purpose or tradeoff
SwiftUI scene composition DestinationVideo/DestinationVideo.swift:14 Keeps windows, volumes, and immersive-space lifecycle visible at the app boundary.
SwiftUI–RealityKit bridge DestinationVideo/Views/visionOS/ImmersiveEnvironmentView.swift:20 Builds and updates a RealityKit entity graph from SwiftUI lifecycle closures.
Explicit immersive-space lifecycle DestinationVideo/Views/visionOS/ImmersiveEnvironmentView.swift:17 Makes immersive presentation a scene transition rather than hidden global state.
Observable state owner DestinationVideo/Player/PlayerModel.swift:21 Shares feature state across multiple views without moving framework resources into view values.
Async update consumer DestinationVideo/Player/PlayerModel.swift:157 Consumes provider or event streams in cancellable structured tasks.
Environment-probe state adapter DestinationVideo/Model/visionOS/ImmersiveEnvironment.swift:84 Maps selected environment state into RealityKit probe blending for reflected video lighting.

Naming conventions

  • Role suffixes are evidence, not decoration: Model: PlayerModel; Coordinator: Coordinator, WatchingCoordinator; Delegate: PlaybackCoordinatorDelegate; View: CategoryListView, CategoryView, ContentView, DetailView, GenreView.
  • Protocols: no app-defined protocol in the reviewed source.
  • Commands use verb-led methods: loadEnvironment, clearEnvironment, requestEnvironmentState, setEnvironmentState, findCommonEntityByName, setVirtualEnvironmentProbeComponent, gatherEntities, setActiveState.
  • Files generally match their primary type; Views, Models, Managers, Providers, Components, Systems, and Packages folders describe architectural roles where present.

Architecture takeaways

  • Treat DestinationVideo as the owner of scene declarations, not as the owner of every RealityKit entity created later.
  • Keep view-local interaction in SwiftUI, but move provider sessions, playback resources, shared game state, or transport state into a stable owner when their lifetime exceeds one render pass.
  • Model immersive-space open, transition, and close states explicitly so windows and immersive content cannot drift apart.

Source map

Source file Relevant symbols
DestinationVideo/Model/visionOS/ImmersiveEnvironment.swift:13 ImmersiveEnvironment, ImmersiveSpaceState
DestinationVideo/Model/visionOS/EnvironmentStateHandler.swift:12 EnvironmentStateType, EnvironmentStateHandler
DestinationVideo/Views/visionOS/ImmersiveEnvironmentView.swift:13 ImmersiveEnvironmentView
DestinationVideo/DestinationVideo.swift:14 DestinationVideo
DestinationVideo/ContentView.swift:11 ContentView
DestinationVideo/Player/PlayerModel.swift:13 Presentation, PlayerModel, PlayerViewObserver
DestinationVideo/Player/SystemPlayerView.swift:14 SystemPlayerView, Coordinator, SystemPlayerView
DestinationVideo/SharePlay/WatchingCoordinator.swift:14 WatchingCoordinator, PlaybackCoordinatorDelegate