Presenting images in RealityKit
At a glance
| Item | Summary |
|---|---|
| Purpose | Create and display spatial scenes in RealityKit |
| App architecture | SpatialPhotosSampleApp owns AppModel; ImagePresentationView turns the selected image and presentation mode into RealityKit entities while ornaments expose lightweight controls. |
| Main patterns | SwiftUI scene composition, UI–RealityKit bridge, Observable state owner, Delegate callback adapter, Presentation-model adapter |
| Project style | Code-rich sample with 7 scanned Swift file(s) and 358 implementation line(s). |
Project structure
Source bundle/
└── SpatialPhotosSample/
└── SpatialPhotosSample/
├── Model/
│ └── AppModel.swift # Spatial3DImageState, AppModel
├── Views/
│ ├── ImagePresentationView.swift # ImagePresentationView
│ ├── ContentView.swift # ContentView
│ └── OrnamentsView.swift # OrnamentsView
├── SpatialPhotosSampleApp.swift # SpatialPhotosSampleApp
└── Delegates/
├── AppDelegate.swift # AppDelegate
└── SceneDelegate.swift # SceneDelegate
Structure observations
- The runtime boundary is WindowGroup; 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
flowchart LR
SpatialPhotosSampleApp_1["SpatialPhotosSampleApp"]
WindowGroup_2["WindowGroup"]
ImagePresentationView_3["ImagePresentationView"]
AppModel_4["AppModel"]
RealityKit_entity_graph_5["RealityKit entity graph"]
image_resources___RealityKit_entities_6["image resources + RealityKit entities"]
SpatialPhotosSampleApp_1 --> WindowGroup_2
WindowGroup_2 --> ImagePresentationView_3
ImagePresentationView_3 --> AppModel_4
AppModel_4 --> RealityKit_entity_graph_5
RealityKit_entity_graph_5 --> image_resources___RealityKit_entities_6
Reference code
SpatialPhotosSample/SpatialPhotosSample/SpatialPhotosSampleApp.swift:11 — executable or app-lifecycle anchor.
struct SpatialPhotosSampleApp: 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
classDiagram
SpatialPhotosSampleApp *-- AppModel : appModel
AppModel *-- Entity : contentEntity
ImagePresentationView o-- AppModel : appModel
AppModel --> Spatial3DImageState : spatial3DImageState
Ownership evidence
SpatialPhotosSample/SpatialPhotosSample/SpatialPhotosSampleApp.swift:12 — representative stored state or nearest verified lifecycle anchor.
@State private var appModel = AppModel()| Owner | Object or state | Relationship | Mutation authority |
|---|---|---|---|
SpatialPhotosSampleApp |
AppModel as appModel |
creates and retains | The declaring type controls writes |
AppModel |
Entity as contentEntity |
creates and retains | The owning type coordinates writes |
ImagePresentationView |
AppModel as appModel |
receives a shared or non-owning reference | The upstream owner controls lifetime; this scope may invoke the exposed mutable API |
AppModel |
Spatial3DImageState as spatial3DImageState |
owns value state | 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 |
|---|---|---|
SpatialPhotosSampleApp (SpatialPhotosSample/SpatialPhotosSample/SpatialPhotosSampleApp.swift:11) |
Declares app lifecycle and top-level dependency lifetime. | App |
ImagePresentationView (SpatialPhotosSample/SpatialPhotosSample/Views/ImagePresentationView.swift:11) |
Presents UI and forwards gestures or lifecycle events. | View |
AppModel (SpatialPhotosSample/SpatialPhotosSample/Model/AppModel.swift:19) |
Owns feature state and domain transitions. | Concrete framework collaborators |
ContentView (SpatialPhotosSample/SpatialPhotosSample/Views/ContentView.swift:11) |
Presents UI and forwards gestures or lifecycle events. | View |
OrnamentsView (SpatialPhotosSample/SpatialPhotosSample/Views/OrnamentsView.swift:11) |
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() (SpatialPhotosSample/SpatialPhotosSample/SpatialPhotosSampleApp.swift:12) |
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
SpatialPhotosSample/SpatialPhotosSample/SpatialPhotosSampleApp.swift:12 — representative visibility boundary.
@State private var appModel = AppModel()Logic ownership and placement
| Logic | Owning type or file | Placement rationale |
|---|---|---|
| Application/command lifecycle | SpatialPhotosSampleApp |
The executable boundary determines app, controller, scene, or command lifetime. |
| Presentation and user intent | ImagePresentationView |
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 | SpatialPhotosSample/SpatialPhotosSample/SpatialPhotosSampleApp.swift:11 |
Keeps windows, volumes, and immersive presentation visible at the app boundary. |
| UI–RealityKit bridge | SpatialPhotosSample/SpatialPhotosSample/Views/ImagePresentationView.swift:17 |
Builds or hosts the RealityKit entity graph from SwiftUI or a platform view/controller lifecycle. |
| Observable state owner | SpatialPhotosSample/SpatialPhotosSample/Model/AppModel.swift:19 |
Keeps shared feature state in a stable owner rather than in transient view values. |
| Delegate callback adapter | SpatialPhotosSample/SpatialPhotosSample/Delegates/AppDelegate.swift:11 |
Inverts imperative framework callbacks into the sample’s owning controller, coordinator, or model. |
| Presentation-model adapter | SpatialPhotosSample/SpatialPhotosSample/Model/AppModel.swift:43 |
Maps selected image representation and display mode into a RealityKit entity without spreading format logic across controls. |
Naming conventions
- Role suffixes are evidence, not decoration: App:
SpatialPhotosSampleApp; Model:AppModel; View:ContentView,ImagePresentationView,OrnamentsView. - Protocols: no app-defined protocol in the reviewed source.
- Commands use verb-led methods:
createImagePresentationComponent,generateSpatial3DImage,scaleImagePresentationToFit,application,scene. - 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
SpatialPhotosSampleAppas 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 |
|---|---|
SpatialPhotosSample/SpatialPhotosSample/Model/AppModel.swift:11 |
Spatial3DImageState, AppModel |
SpatialPhotosSample/SpatialPhotosSample/Views/ImagePresentationView.swift:11 |
ImagePresentationView |
SpatialPhotosSample/SpatialPhotosSample/SpatialPhotosSampleApp.swift:11 |
SpatialPhotosSampleApp |
SpatialPhotosSample/SpatialPhotosSample/Delegates/AppDelegate.swift:11 |
AppDelegate |
SpatialPhotosSample/SpatialPhotosSample/Views/ContentView.swift:11 |
ContentView |
SpatialPhotosSample/SpatialPhotosSample/Views/OrnamentsView.swift:11 |
OrnamentsView |
SpatialPhotosSample/SpatialPhotosSample/Delegates/SceneDelegate.swift:10 |
SceneDelegate |