Multi-sensory spatial awareness for blind and low-vision users β turning LiDAR depth into touch and sound, entirely on-device.
My submission to Apple's Swift Student Challenge 2026 π
English Β· π«π· FranΓ§ais
Close your eyes and try to cross a room. Every step is a question.
An iPad Pro carries a LiDAR scanner that measures the exact distance to everything in front of it, sixty times per second. That data usually feeds AR games and room-scanning apps β but what if it could feed your other senses instead?
Sonic Vision converts real-time depth into two intuitive channels:
- π€² Haptics β the closer an obstacle, the stronger and sharper the vibration, following an inverse-exponential curve that matches human perception (not a naive linear mapping).
- π§ 3D spatial audio β a sonar-like ping, positioned in real 3D space around your head with HRTF rendering. An obstacle on your left sounds like it's on your left.
- π£οΈ On-device recognition β the Vision framework identifies people and objects in the scene and surfaces them as floating AR labels, with no ML model file and no cloud.
Point the iPad at the world, and the world answers back β through your hands and your ears. All of it computed on-device, with zero network calls and zero data collection.
β οΈ Sonic Vision is an experimental, complementary tool β not a medical device, and not a replacement for a white cane, a guide dog, or O&M training. See Disclaimers.
I wanted my Swift Student Challenge entry to be more than a demo β I wanted it to argue something: that serious accessibility tools can be tiny, private, and immediate.
The challenge imposes brutal constraints: a Swift Playgrounds app (.swiftpm), under 25 MB, judged in about three minutes, working fully offline. Most people treat those constraints as limits. I treated them as the design brief:
- No CoreML model file. Instead of shipping a multi-megabyte network, I combined the Vision framework's built-in detectors (
VNDetectHumanRectanglesRequest,VNDetectRectanglesRequest,VNClassifyImageRequest) with geometric heuristics. Detection costs 0 bytes of assets. - No audio files. Every sonar ping is a sine wave synthesized programmatically β PCM buffers pre-cached at 400 / 800 / 1200 Hz with an anti-click envelope, then spatialized through
AVAudioEnvironmentNodewith HRTF-HQ rendering. - No external dependencies. Pure Apple frameworks, nothing else.
The result: the entire app is ~100 KB of source β about 0.4% of the size budget.
There's also an unusual production detail I'm a little proud of: this iPad LiDAR app was engineered without a Mac. The target IDE is Swift Playgrounds on iPad, and the codebase was developed and audited from a Windows/WSL2 environment β which forced a discipline of architecture-first thinking, careful API reading, and systematic review instead of trial-and-error compiling.
And that discipline got tested. Before submission I ran a full pre-submission audit (AUDIT_REPORT.md β kept in this repo on purpose, bugs and all). It found 9 issues, including three genuinely humbling ones:
- π³οΈ The AR camera view was silently running its own separate
ARSession, disconnected from the depth pipeline β the app would have demoed a black screen. - β‘ A race condition on the camera pixel buffer, written from ARKit's thread and read from the main thread.
- π A double multiplication of haptic intensity that turned the sensitivity slider quadratic instead of linear.
Every critical issue was fixed, the sonar overlay and AR labels were built, and the project grew from 1,441 to ~2,000 lines β leaner in behavior, richer in experience. Shipping the audit alongside the code is the point: engineering isn't pretending bugs never existed; it's finding them before your users (or a jury) do.
flowchart LR
L["π‘ ARKit<br/>LiDAR sceneDepth<br/>10 Hz"] --> M["ARSessionManager"]
M -->|"DepthFrame"| VM["SonicViewModel<br/>(Combine)"]
M -->|"CVPixelBuffer"| V["VisionDetector<br/>2 Hz throttle"]
V -->|"DetectedObject[]"| VM
VM --> H["π€² HapticEngine<br/>Core Haptics"]
VM --> A["π§ SpatialAudioEngine<br/>AVAudioEngine + HRTF"]
VM --> U["β¨ SwiftUI<br/>Sonar overlay + AR labels"]
The whole experience is a real-time translation table between distance and sensation:
| Distance | Haptic feedback | Audio ping |
|---|---|---|
| 3.0 m | barely perceptible hum | slow, low (~400 Hz) |
| 1.5 m | gentle pulse | steady rhythm (~800 Hz) |
| 0.5 m | strong, sharp | fast, bright (~1200 Hz) |
| 0.2 m | maximum urgency | near-continuous β danger |
Each service runs on its own cadence so no channel can starve another:
| Service | Framework | Rate | Role |
|---|---|---|---|
ARSessionManager |
ARKit | 10 Hz | LiDAR depth capture, ROI sampling, simulation fallback |
HapticEngine |
Core Haptics | 20 Hz max | continuous patterns, auto-restart on engine reset |
SpatialAudioEngine |
AVFoundation | ~6.6 Hz | HRTF 3D positioning, pre-cached sine buffers |
VisionDetector |
Vision | 2 Hz | on-device people/object detection, confidence gating |
- π 100% offline, privacy-first β no network calls, no analytics, no data ever leaves the device
- π€² Progressive haptics β perceptually-tuned inverse-exponential intensity curve with user scaling
- π§ True 3D audio β HRTF rendering places pings in space (AirPods recommended)
- ποΈ On-device detection β people and objects, zero ML model files
- π Animated sonar overlay β concentric pulse waves, color-coded by proximity (cyan β orange β red)
- π«§ Liquid Glass design system β
.ultraThinMaterialthroughout, SF Rounded type scale, spring physics on every interaction - π Graceful degradation β simulation mode on iPads without LiDAR, engine auto-recovery, permission flows
MVVM + Services, wired with Combine. Views never touch a service directly β everything flows through the ViewModel.
SonicVision.swiftpm/ ~2,000 LOC Β· 17 Swift files Β· ~100 KB
βββ App SonicVisionApp
βββ Views MainView Β· ARCameraView Β· ControlPanelView Β· SonarOverlayView
β ARLabelNode Β· LiquidGlassCard Β· AccessibilityBadge
βββ ViewModel SonicViewModel (central state + coordination)
βββ Services ARSessionManager Β· HapticEngine Β· SpatialAudioEngine Β· VisionDetector
βββ Models DepthFrame Β· DetectedObject Β· HapticPattern
βββ Design DesignSystem (Typo / Space / Radius / Anim tokens)
Engineering choices worth noting:
- Event-driven pipeline with independent throttles per service (50 / 100 / 150 / 500 ms) β a slow frame in one channel never blocks the others.
- Region-of-interest depth sampling (center ~10% + lateral zones) instead of scanning the full depth buffer.
- Low-pass smoothed values to kill LiDAR jitter before it reaches your fingertips.
- No force unwraps, deterministic cleanup β every service owns its
deinit, the haptic engine self-heals viastoppedHandler/resetHandler.
Requirements: iPad Pro (2020+) with LiDAR Β· iPadOS 17+ Β· headphones recommended (AirPods Pro ideal). iPads without LiDAR get a simulated demo mode.
- Clone the repo (or grab
SonicVision.swiftpm) - Open
SonicVision.swiftpmin Swift Playgrounds 4+ on iPad β or in Xcode 15+ on Mac - Build & run, grant camera access, press Start, and point the iPad at the room
- Move toward a wall. Feel it before you touch it. π€²
45-second demo path (the challenge cut): scan a cluttered desk β approach one object and feel the haptics climb β pan across the room and watch three objects get labeled while the audio tracks them in space. Full script in Demo/Script_demo.md.
| Path | What it is |
|---|---|
SonicVision.swiftpm/ |
The app β complete Swift Playgrounds package |
Document_tech/TECHNICAL_DOSSIER.md |
The build blueprint written before coding: architecture, data flow, 8-phase plan, thresholds |
AUDIT_REPORT.md |
The unvarnished pre-submission audit β 9 bugs found, criticals fixed |
Demo/Script_demo.md |
The 45-second demo storyboard |
These process documents are published deliberately: the how is as much the portfolio piece as the what.
Sonic Vision is not a medical device. It is an experimental, complementary spatial-awareness tool and has not been evaluated by any medical or regulatory authority. It does not replace a white cane, a guide dog, orientation & mobility training, or any established assistive technology.
Privacy: all processing happens on-device. No camera frames, depth data, or usage data is ever transmitted, stored, or shared.
I'm Nathan (@SynnIA), a French developer who likes building complete products under tight constraints β and believes the best proof of engineering skill is what you can do with less: less size, less dependency, less data collected.
Sonic Vision is my Swift Student Challenge 2026 entry: four Apple frameworks orchestrated in real time, in ~100 KB, with nothing to hide β not even the audit report.
MIT License Β· Built with Swift, ARKit, and a conviction that accessibility deserves beautiful engineering.
Swift Student Challenge 2026
Built with care by Nathan Fernandes β Founder of SYNN-IA Β· Dijon, France