Inside the project
Prepared with the project’s development agent from source and retained evidence. This is a project-owner assessment, not an independent customer review. Dated checks were not rerun for this website.
iOS Vitals is most useful as an inspectable, honest camera-PPG stack: put a fingertip on an iPhone 11 Pro's rear camera and it delivers pulse rate, beat-to-beat (R-R) intervals, HRV statistics and breathing rate, with live quality scoring, haptic placement guidance and one-button operation. Its strongest working capabilities are the hardened pulse pipeline — adaptive torch/exposure control plus explicit defenses against the harmonic half-lock that plagues camera pulse apps, verified against the owner's manually checked rates in June–July 2026 — and its engineering honesty: a frozen API/provenance contract (Sensing Baseline 1.0, 169 passing XCTests on 2026-08-10), estimators that decline rather than fabricate, and research-only labeling on every uncalibrated figure. Practical limits are equally clear: blood-pressure, oxygen and arousal outputs are uncalibrated research estimates (the uncalibrated camera-BP path is compression-bounded by construction; haptic-vibrometric absolute mmHg is physically infeasible on this hardware), no metric has formal reference-hardware accuracy statistics yet, and there is no public release. Next priorities: run the written ECG ground-truth protocol, wire the tested measurement orchestrator into the app session flow, and finish the active respiration-estimator branch. Status: wellness / research. Non-diagnostic.
What stands out
- On-device-verified pulse, R-R/HRV and respiration from stock iPhone hardware, fully offline
- Harmonic half-lock defenses (plausibility gates, 6% temporal folding, opt-in YIN + Kalman tracker) fixed real mis-reads reproduced from recorded sessions
- Honest-by-design: frozen Sensing Baseline 1.0 contract, provenance strings per metric, estimators that decline without calibration, non-diagnostic labeling throughout
- Complete research telemetry loop: live USB JSONL streaming, 30 recorded sessions, Python analyzer producing Markdown/CSV/series reports
Current limits
- BP, SpO2 and arousal are uncalibrated research estimates; uncalibrated camera BP cannot leave roughly 100-143/69-96 mmHg by construction
- Vibrometric absolute BP infeasible on iPhone 11 Pro (100 Hz IMU vs 150-230 Hz actuator, no force sensor); relative signal only
- No Bland-Altman validation against reference hardware yet (protocol written, not executed); single test device; no public release
- Respiration needs stillness and >=20 s windows; measurement orchestrator app wiring still pending on-device validation
Features & evidence
Camera PPG capture + guidance
installed-testedUser rests a fingertip on the rear camera; torch lights, haptic ticks confirm good placement, quality score gates output
Recorded evidence
30 telemetry sessions 2026-06-08..06-11 in TelemetryLogs/; June 2026 adaptive-torch/exposure fixes
Pulse rate with harmonic-lock defenses
installed-testedUser watches the pulse tile lock within ~30-60 s; sub-harmonic mis-locks are rejected automatically
Recorded evidence
June-July 2026 fix series verified against owner's true 112-117 bpm sessions; unit-tested (169 XCTests at 2026-08-10 freeze)
R-R intervals + HRV (SDNN/RMSSD)
installed-testedTiles populate once enough clean beats accumulate; rate-jump outliers rejected
Recorded evidence
Same June 2026 sessions; outlier-rejection unit tests
Respiration estimator (RIIV/RIAV/RIFV fusion)
component-testedBreathing rate appears after a >=20 s agreeing window
Recorded evidence
Synthetic validation only (SensingBaseline-1.0.md); active branch feat/respiration-estimator, review-fix commits Oct 2026
Sensing Baseline 1.0 API/provenance contract
component-testedIntegrators consume frozen producer APIs with provenance strings per metric
Recorded evidence
docs/SensingBaseline-1.0.md: 169 XCTests pass, simulator BUILD SUCCEEDED, git tag sensing-baseline-1.0, 2026-08-10
Camera BP (uncalibrated research estimate)
installed-testedTile shows 'Cam est' with research footnote
Recorded evidence
docs/camera_bp_pinning.md (Aug 2026): compression-bounded by construction; research-only
Camera BP (cuff-calibrated model path)
sourceDeclines to display until the user calibrates once against a real cuff
Recorded evidence
docs/camera_bp_pinning.md (Aug 2026, ~90%); no on-device validation
Vibrometric BP primitives
installed-testedHaptic-excitation research capture with export; labeled uncalibrated
Recorded evidence
Aug 2026 hardware feasibility study: absolute mmHg infeasible; relative research signal only
Arousal proxy (oculomotor)
installed-testedRelative-arousal tile, explicitly a proxy
Recorded evidence
Aug 2026 feasibility study; UI relabeled Aug 2026
Measurement orchestrator (staged pulse-lock -> BP)
component-testedSession advances priming -> pulse lock (>=0.99 x5) -> deviation tracking -> BP stage
Recorded evidence
docs/measurement_orchestration.md (Aug 2026, ~80%): pure logic done + tested, app wiring pending
USB telemetry + desktop analyzer
installed-testedLive JSONL stream over cable; Ctrl-C saves session; Python analyzer emits Markdown/CSV/series
Recorded evidence
TelemetryLogs/ 30 sessions + 2 full-analysis report sets generated 2026-06-08
Ground-truth validation vs Polar H10 ECG
plannedBland-Altman acceptance study for HR/RR
Recorded evidence
docs/GroundTruthValidationProtocol.md: protocol written, not executed
Review updates & corrections
- No committed changes since the 17 Oct biography; same branch feat/respiration-estimator, same head (9fe5712 'Review fixes: unbiased respiratory phase + robustness + honest confidence')
- Uncommitted working-tree modifications exist to Sources/iOSVitalsKit/DSP/PulseDetector.swift, Facade/PPGAnalysisEngine.swift, ExampleApp/SimpleVitalsHomeView.swift, ExampleApp/VibrometricResearchController.swift and Tests/PPGDSPTests.swift — in-progress respiration/pulse refinement, unverified; do not describe as shipped
- No corrections to the biography; the conflict notes there (stale SpO2 mention in README, VitalsEngine not imported by the app, 169 as the authoritative test count, 'Android' filename quirk) all still apply
Workflow walkthrough
A guide to the native workflow. These steps describe the app; only the recordings and images embedded on this page are available as website demonstrations.
- Run the install script with the iPhone cabled; it installs the app and starts a live telemetry stream in the terminal
- Open the single-page app and press Start, then rest a fingertip over the rear camera; the torch lights
- Hold still; gentle haptic ticks confirm good placement and the pulse tile locks within about a minute
- Watch R-R, HRV and breathing-rate tiles fill in as confidence rises; research-estimate tiles stay clearly labeled non-diagnostic
- Press Ctrl-C in the terminal to save a timestamped JSONL session into TelemetryLogs/
- Run the bundled Python analyzer on the JSONL to produce a Markdown report, CSV and numeric time series
Planned captures · not yet available
- Proposed: device screen recording of a full measurement session (idle -> finger placement -> pulse lock -> results)
Development biography · earlier archive
Development profile compiled from project source and retained records in October 2026. Dates and test results describe those records; they do not imply a new build, live acceptance test or public release.
Scope assigned: the iOS Vitals research app and its implemented measurement pipelines. Read-only inspection of the repository at the project archive; no builds, no app operation, no edits. Every claim below is source-backed; exact paths are in §10. Experimental estimates are explicitly separated from validated use throughout.
Biography
Smartphone cameras have been able to see a pulse for over a decade: press a fingertip over the lens, light it with the torch, and each heartbeat changes how much light the blood-filled tissue transmits. The hard part has never been seeing the signal — it is not fooling yourself about it. Consumer "vitals" apps routinely report half or double the true heart rate when the optical signal's harmonics confuse the estimator, show blood-pressure numbers that are mathematically incapable of leaving the normal range, and present all of it with medical-looking confidence. iOS Vitals was built, starting June 2026, as a research response to exactly that problem: extract everything an iPhone 11 Pro's hardware can genuinely measure, and label everything it cannot.
The project is a two-layer codebase. iOSVitalsKit, the Swift library, owns capture and signal processing: an AVFoundation camera pipeline with an adaptive torch controller and exposure management tuned for stable 30 fps fingertip capture; conversion of frames to an optical-density series; band-pass filtering; beat and beat-onset (foot) fiducial detection; inter-beat-interval statistics (SDNN, RMSSD and friends); a respiration estimator that fuses three independent respiratory modulations of the PPG wave (intensity, amplitude and frequency) with zero-phase filtering and agreement gating; and spectral quality scoring that tells the app when not to trust a window of data. ExampleApp is the deliberately simple face of it: one page, eight tiles, a start button. A session is one button press — haptics tick when finger placement is good, tiles fill in as confidence rises, and results export to CSV or stream live over USB as JSON lines for desktop analysis.
What distinguishes the project is that its hardest engineering went into refusing bad answers. The pulse pipeline was hardened through June–July 2026 against the classic failure modes of camera PPG, each one reproduced from the studio’s real recorded sessions: frame-rate collapse silently starving the estimator (fixed with adaptive torch/exposure caps and explicit telemetry of effective fps), and the notorious harmonic half-lock, where a 117 bpm pulse is reported as 58 or 78 because a sub-harmonic wins the spectral vote (fixed with plausibility gates, temporal harmonic folding, and an opt-in YIN-plus-Kalman harmonic tracker). The same honesty governs the research estimators. An internal audit proved the uncalibrated camera blood-pressure path is compression-bounded — by construction it can only output roughly 100–143 over 69–96 mmHg, so it can never represent real hypertension or hypotension. Rather than hide that, the project documented it, built a feature-extraction and ridge-regression path that works only with per-user cuff calibration, and made the estimator decline to answer instead of emitting a pinned constant. A separate hardware-feasibility study concluded that vibrometric (haptic-excitation) blood pressure cannot produce absolute mmHg on this phone at all — the motion sensor samples at 100 Hz while the haptic actuator rings at 150–230 Hz, and the force reference died with 3D Touch — so the UI labels it a research estimate, and pupil-based autonomic readouts were renamed an "arousal proxy." The on-screen footnote is blunt: BP, O₂ and arousal are uncalibrated research estimates, not medical readings.
The intended audience is researchers, biosignal hobbyists and developers who want a serious, inspectable PPG stack on stock iPhone hardware — not patients. The repository's own capability-boundaries section says plainly that this is not a clinical blood-pressure monitor or ECG. For integrators, the project froze Sensing Baseline 1.0 on 2026-08-10: a documented API and provenance contract (every metric carries a provenance string such as pulse-phase(ppg)/1), verified at freeze time by 169 passing XCTests and a successful simulator build, and tagged in git. A companion Ground-Truth Validation Protocol defines how the wellness-grade metrics graduate: Bland–Altman comparison against a Polar H10 ECG strap with sub-30 ms clock sync, acceptance gates for heart rate (±3 bpm bias) and respiration, and respiratory sinus arrhythmia as a positive control — while explicitly keeping SpO₂ and blood pressure outside any acceptance gate.
A concrete user journey: you install the app onto a cabled iPhone with one script, which also starts a live telemetry stream to your Mac. You press Start and rest a fingertip over the rear camera; the torch lights, and gentle haptic ticks confirm good placement. Over the next minute or two the pulse tile locks, R-R intervals and HRV appear once enough clean beats accumulate, and breathing rate follows once a 20-second window agrees across fusion channels. You press Ctrl-C in the terminal and a timestamped JSONL session file lands in TelemetryLogs/, ready for the bundled Python analyzer to turn into a Markdown report, CSV and numeric time series — thirty such real sessions from June 2026 live in the repository as evidence.
Current work (branch feat/respiration-estimator, October 2026) extends the respiration estimator with unbiased respiratory phase, adds an exact beat-onset event source, and fixes cardiac-phase replay aliasing — groundwork for the staged measurement orchestrator that requires a ≥99% pulse lock before any downstream estimate runs.
Modules and features
Dependencies: Apple frameworks only in the shipping app (AVFoundation, CoreHaptics, CoreMotion, SwiftUI, HealthKit). Local packages FIRFilters, Kalman/KalmanCore, RemezEngine support the harmonic tracker and VitalsEngine. No third-party network services; fully offline.
What a visitor can see or try: nothing is publicly downloadable; a visitor can see the app icon, the documented one-button workflow, and (if the owner approves) excerpts of real telemetry reports. There are currently no UI screenshots or demo videos on disk (§7).
4b. Related module: VitalsEngine (separate coverage, brief)
A standalone SwiftPM package inside the repo: actor-based orchestrator emitting a 1 Hz VitalsSnapshot, modules for Core/Pipeline (FIRFilters + KalmanCore), BloodPressure (Route A PWA-calibrated, Route B oscillometric), Autonomic (pupillometry), Capture. It is a parallel next-generation implementation and is not imported by the shipping app — a documented drift risk, not a product. It should be presented on the site, if at all, as an in-progress engine rewrite.
Technical foundations
Swift / SwiftUI / SwiftPM throughout; AVFoundation capture with torch control; CoreHaptics for guidance and vibrometric excitation; CoreMotion for IMU; HealthKit (opt-in research consent, default off). DSP is authored in-repo (FIR band-pass, zero-phase filtering, spectral estimation, YIN pitch tracking, Kalman harmonic tracking via local Kalman/KalmanCore and FIRFilters packages; RemezEngine for filter design). Host-side tooling is zsh + libimobiledevice (idevicesyslog) + Python for session analysis. The scientific grounding is written up in Vitals_Research_and_Architecture.md with literature citations (e.g., Charlton 2016 on PPG-derived respiration; Mukkamala 2025 on cuffless-BP skepticism; the UCSD VibroBP paper, Sci Rep 2024, DOI 10.1038/s41598-024-75025-9, which motivated the vibrometric feasibility verdict).
Maturity by feature (dated evidence)
| Feature | Status |
|---|---|
| Camera PPG capture + torch/exposure management | Implemented, tested, on-device verified |
| Pulse rate + harmonic-lock defenses | Implemented, tested, on-device verified |
| R-R / HRV metrics | Implemented, tested, on-device verified |
| Respiration estimator (fusion) | Implemented, tested; under active refinement |
| Sensing Baseline 1.0 (frozen API/provenance) | Frozen 2026-08-10 |
| Camera BP (uncalibrated) | Implemented but compression-bounded by design; research-only |
| Camera BP (calibrated model path) | Source implemented; declines without calibration; no on-device validation |
| Vibrometric BP | Primitives implemented; absolute mmHg infeasible on this hardware — relative research signal only |
| Arousal proxy (oculomotor) | Implemented as loose relative proxy only |
| Measurement orchestrator | Pure logic done + tested (~80%); app wiring pending on-device validation |
| Ground-truth validation vs ECG reference | Protocol written; not yet executed |
| Public release / App Store | None — installed from source via script |
Unknowns: no formal accuracy statistics exist yet for any metric (the Bland–Altman study is designed but not run); current test count on the working branch is unknown (last verified 169 at the 2026-08-10 freeze).
Roadmap, limitations, FAQs
Roadmap (from repo docs, not aspirational invention): execute the Ground-Truth Validation Protocol (Polar H10 ECG, n=1→5–8, Bland–Altman gates); wire the measurement orchestrator into the app session flow and validate on device; finish the respiration-estimator branch; optional cuff-calibration flow to enable the model-backed BP path; converge or retire the parallel VitalsEngine package; README "Next Upgrades" and Vibrometric Build Order v0.1–v0.4 list further steps.
Known limitations: non-diagnostic by design; uncalibrated BP is compression-bounded and cannot detect hyper/hypotension; vibrometric absolute BP is physically infeasible on iPhone 11 Pro (100 Hz IMU vs 150–230 Hz actuator, no force sensor); pupil-based autonomic readout is a loose arousal proxy at best; HRV and respiration need stillness and long windows; validation against reference hardware not yet performed; single test device.
FAQs:
- Is this a medical device? No. Everything is labeled "wellness / research. Non-diagnostic." BP, O₂ and arousal figures are uncalibrated research estimates and must not guide any health decision.
- Why does the blood-pressure tile say "Cam est" and sometimes refuse to show a number? The uncalibrated path can only produce normal-range numbers, so the honest, model-backed path declines to answer unless you calibrate once against a real cuff.
- How accurate is the pulse? After the mid-2026 hardening it matched the studio’s manually verified rates (including 112–117 bpm sessions) where earlier builds half-locked; formal accuracy statistics await the ECG-reference study.
- What do I need to run it? An iPhone (developed on iPhone 11 Pro), Xcode to build, and optionally a Mac with libimobiledevice for live USB telemetry. It runs fully offline.
- Can I download it? Not currently — there is no public release; it is a research codebase installed from source.