# darkwingtori/grafiti-vision architecture

> Architecture diagram of the GitHub repository darkwingtori/grafiti-vision, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-30). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/darkwingtori/grafiti-vision
- Repository: https://github.com/darkwingtori/grafiti-vision

## Overview

Jet Set Vision is an iOS AR graffiti app: users grant camera access, aim at detected surfaces, choose a design, place and manipulate it in the live AR scene, then capture and browse saved images. The camera screen orchestrates Spray and Vision modes; ARKit tracking and plane detection support placement, while Apple Vision classifies frames and detects people only in Vision Mode. Captures are stored locally as JPEGs with a Codable JSON index. The graph follows the provided source excerpts and index; unsampled implementations are included only where documented, and uncertain connections are omitted.

Main entry points: [`JetSetVision/Features/Camera/CameraView.swift`](https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/Features/Camera/CameraView.swift) (Camera screen), [`JetSetVision/AR/ARViewContainer.swift`](https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/AR/ARViewContainer.swift) (AR view bridge), [`JetSetVision/Features/Spray/GraffitiPlacementController.swift`](https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/Features/Spray/GraffitiPlacementController.swift) (Graffiti placement), [`JetSetVision/AR/ARCaptureController.swift`](https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/AR/ARCaptureController.swift) (AR capture)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_experience["App experience"]
  node_app["App entry"]
  node_camera["Camera screen<br/>[CameraView.swift]"]
  node_permission["Camera permission"]
  node_visionui["Vision overlay"]
  node_appstate["Mode state<br/>[AppState.swift]"]
end

subgraph group_ar["AR and perception"]
  node_arview["AR view bridge"]
  node_session["AR session"]
  node_planes["Plane detection"]
  node_vision["Vision processing"]
end

subgraph group_graffiti["Graffiti creation"]
  node_picker["Graffiti picker"]
  node_placement["Graffiti placement"]
  node_assetmodel["Graffiti designs"]
  node_artwork["Artwork assets<br/>[Assets.xcassets]"]
  node_renderer["Graffiti renderer"]
end

subgraph group_captures["Capture library"]
  node_capture["AR capture"]
  node_gallery["Capture gallery<br/>[GalleryView.swift]"]
  node_store[("Capture store<br/>[CaptureStore.swift]")]
  node_capturemodel["Capture metadata<br/>[Capture.swift]"]
end

node_user(("User"))

node_user -->|"opens"| node_app
node_app -->|"shows"| node_camera
node_user -->|"uses"| node_camera
node_camera -->|"requests access"| node_permission
node_camera -->|"hosts"| node_arview
node_arview -->|"configures"| node_session
node_session -->|"forwards anchors"| node_planes
node_session -->|"offers frames"| node_vision
node_camera -->|"shows in Vision Mode"| node_visionui
node_visionui -->|"displays results"| node_vision
node_camera -->|"switches mode"| node_appstate
node_arview -->|"checks mode"| node_appstate
node_arview -->|"routes taps"| node_placement
node_camera -->|"shows in Spray Mode"| node_picker
node_picker -->|"updates selection"| node_placement
node_picker -->|"lists designs"| node_assetmodel
node_assetmodel -->|"names bundled art"| node_artwork
node_placement -->|"requests material"| node_renderer
node_placement -->|"places selected design"| node_assetmodel
node_arview -->|"attaches AR view"| node_capture
node_camera -->|"starts capture"| node_capture
node_capture -->|"hides highlight"| node_placement
node_capture -->|"saves snapshot"| node_store
node_store -->|"indexes records"| node_capturemodel
node_camera -->|"opens gallery"| node_gallery
node_gallery -->|"loads and deletes"| node_store
node_gallery -->|"shows records"| node_capturemodel

click node_app "https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/App/JetSetVisionApp.swift"
click node_camera "https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/Features/Camera/CameraView.swift"
click node_permission "https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/Services/CameraPermissionService.swift"
click node_arview "https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/AR/ARViewContainer.swift"
click node_session "https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/AR/ARSessionManager.swift"
click node_planes "https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/AR/PlaneDetector.swift"
click node_vision "https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/AR/VisionProcessor.swift"
click node_visionui "https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/Features/Vision/VisionModeView.swift"
click node_appstate "https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/App/AppState.swift"
click node_picker "https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/Features/Spray/GraffitiPicker.swift"
click node_placement "https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/Features/Spray/GraffitiPlacementController.swift"
click node_assetmodel "https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/Models/GraffitiAsset.swift"
click node_artwork "https://github.com/darkwingtori/grafiti-vision/tree/main/JetSetVision/Resources/Assets.xcassets"
click node_renderer "https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/Services/GraffitiRenderer.swift"
click node_capture "https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/AR/ARCaptureController.swift"
click node_gallery "https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/Features/Gallery/GalleryView.swift"
click node_store "https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/Services/CaptureStore.swift"
click node_capturemodel "https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/Models/Capture.swift"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_app,node_camera,node_permission,node_visionui,node_appstate,node_user toneBlue
class node_arview,node_session,node_planes,node_vision toneAmber
class node_picker,node_placement,node_assetmodel,node_artwork,node_renderer toneMint
class node_capture,node_gallery,node_store,node_capturemodel toneRose
```

## Components

### App experience

- [App entry](https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/App/JetSetVisionApp.swift): `JetSetVision/App/JetSetVisionApp.swift`
- [Camera screen](https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/Features/Camera/CameraView.swift): `JetSetVision/Features/Camera/CameraView.swift`
- [Camera permission](https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/Services/CameraPermissionService.swift): `JetSetVision/Services/CameraPermissionService.swift`
- [Vision overlay](https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/Features/Vision/VisionModeView.swift): `JetSetVision/Features/Vision/VisionModeView.swift`
- [Mode state](https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/App/AppState.swift): `JetSetVision/App/AppState.swift`

### AR and perception

- [AR view bridge](https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/AR/ARViewContainer.swift): `JetSetVision/AR/ARViewContainer.swift`
- [AR session](https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/AR/ARSessionManager.swift): `JetSetVision/AR/ARSessionManager.swift`
- [Plane detection](https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/AR/PlaneDetector.swift): `JetSetVision/AR/PlaneDetector.swift`
- [Vision processing](https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/AR/VisionProcessor.swift): `JetSetVision/AR/VisionProcessor.swift`

### Graffiti creation

- [Graffiti picker](https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/Features/Spray/GraffitiPicker.swift): `JetSetVision/Features/Spray/GraffitiPicker.swift`
- [Graffiti placement](https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/Features/Spray/GraffitiPlacementController.swift): `JetSetVision/Features/Spray/GraffitiPlacementController.swift`
- [Graffiti designs](https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/Models/GraffitiAsset.swift): `JetSetVision/Models/GraffitiAsset.swift`
- [Artwork assets](https://github.com/darkwingtori/grafiti-vision/tree/main/JetSetVision/Resources/Assets.xcassets): `JetSetVision/Resources/Assets.xcassets`
- [Graffiti renderer](https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/Services/GraffitiRenderer.swift): `JetSetVision/Services/GraffitiRenderer.swift`

### Capture library

- [AR capture](https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/AR/ARCaptureController.swift): `JetSetVision/AR/ARCaptureController.swift`
- [Capture gallery](https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/Features/Gallery/GalleryView.swift): `JetSetVision/Features/Gallery/GalleryView.swift`
- [Capture store](https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/Services/CaptureStore.swift): `JetSetVision/Services/CaptureStore.swift`
- [Capture metadata](https://github.com/darkwingtori/grafiti-vision/blob/main/JetSetVision/Models/Capture.swift): `JetSetVision/Models/Capture.swift`

### Other components

- **User**

## Connections

- User → App entry: opens (evidence: `JetSetVision/App/JetSetVisionApp.swift`)
- App entry → Camera screen: shows (evidence: `JetSetVision/App/JetSetVisionApp.swift`)
- User → Camera screen: uses (evidence: `readme.md`)
- Camera screen → Camera permission: requests access (evidence: `JetSetVision/Features/Camera/CameraView.swift`)
- Camera screen → AR view bridge: hosts (evidence: `JetSetVision/Features/Camera/CameraView.swift`)
- AR view bridge → AR session: configures (evidence: `JetSetVision/AR/ARViewContainer.swift`)
- AR session → Plane detection: forwards anchors (evidence: `JetSetVision/AR/ARSessionManager.swift`)
- AR session → Vision processing: offers frames (evidence: `JetSetVision/AR/ARSessionManager.swift`)
- Camera screen → Vision overlay: shows in Vision Mode (evidence: `JetSetVision/Features/Camera/CameraView.swift`)
- Vision overlay → Vision processing: displays results (evidence: `JetSetVision/Features/Vision/VisionModeView.swift`)
- Camera screen → Mode state: switches mode (evidence: `JetSetVision/Features/Camera/CameraView.swift`)
- AR view bridge → Mode state: checks mode (evidence: `JetSetVision/AR/ARViewContainer.swift`)
- AR view bridge → Graffiti placement: routes taps (evidence: `JetSetVision/AR/ARViewContainer.swift`)
- Camera screen → Graffiti picker: shows in Spray Mode (evidence: `JetSetVision/Features/Camera/CameraView.swift`)
- Graffiti picker → Graffiti placement: updates selection (evidence: `JetSetVision/Features/Spray/GraffitiPicker.swift`)
- Graffiti picker → Graffiti designs: lists designs (evidence: `JetSetVision/Features/Spray/GraffitiPicker.swift`)
- Graffiti designs → Artwork assets: names bundled art (evidence: `JetSetVision/Models/GraffitiAsset.swift`)
- Graffiti placement → Graffiti renderer: requests material (evidence: `JetSetVision/Features/Spray/GraffitiPlacementController.swift`)
- Graffiti placement → Graffiti designs: places selected design (evidence: `JetSetVision/Features/Spray/GraffitiPlacementController.swift`)
- AR view bridge → AR capture: attaches AR view (evidence: `JetSetVision/AR/ARViewContainer.swift`)
- Camera screen → AR capture: starts capture (evidence: `JetSetVision/Features/Camera/CameraView.swift`)
- AR capture → Graffiti placement: hides highlight (evidence: `JetSetVision/AR/ARCaptureController.swift`)
- AR capture → Capture store: saves snapshot (evidence: `JetSetVision/AR/ARCaptureController.swift`)
- Capture store → Capture metadata: indexes records (evidence: `JetSetVision/Services/CaptureStore.swift`)
- Camera screen → Capture gallery: opens gallery (evidence: `JetSetVision/Features/Camera/CameraView.swift`)
- Capture gallery → Capture store: loads and deletes (evidence: `JetSetVision/Features/Gallery/GalleryView.swift`)
- Capture gallery → Capture metadata: shows records (evidence: `JetSetVision/Features/Gallery/GalleryView.swift`)
