Skip to content

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

1 watching

Forks

Latest commit

 

History

1,379 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MyFitnessJournal

A personal training journal for iPhone, iPad & Apple Watch.
repo: StepTrackerTCA

CI Swift 6.2 iOS 26+ iPadOS 26+ watchOS 26+ TCA SwiftUI

A multi-platform fitness ecosystem built with SwiftUI and The Composable Architecture. What started as a TCA learning exercise (inspired by Sean Allen's course) grew into a modular system of two products sharing one foundation of local Swift packages.


🎯 Vision

Build a personal-yet-extensible fitness platform that:

  • Treats your workouts as data you own — local-first SQLite storage with CloudKit sync across your devices, no third-party cloud or analytics.
  • Bridges the consumer-grade Apple Health ecosystem with serious training tools — CrossFit / strength athletes get per-WOD score tracking, training readiness, per-exercise analytics, heart-rate zones and on-device AI plan parsing, all on top of HealthKit primitives.
  • Scales from solo athlete to group gym — the same domain core powers a personal iPhone+Watch journal and an iPad coach dashboard that monitors a roomful of athletes over Bluetooth.
  • Demonstrates modern iOS architecture in production — strict Swift 6 concurrency, TCA composition, Strategy/Client patterns, modular SPM packages with CloudKit sync, and a SwiftUI "view facade" convention separating structure from styling.

📱 MyFitnessJournal — personal training journal (iPhone + Watch)

A personal companion for tracking workouts, recovery and progress.

  • Live workouts with heart-rate tracking — a single session started and controlled from either iPhone or Apple Watch, mirrored across both devices (HKWorkoutSession + WatchConnectivity). Watch-primary and iPhone-primary modes with BLE HR sensor support (iOS 26 native).
  • Plan scanning with on-device AI & OCR — photograph a training plan / WOD and the app extracts the exercises. Three pluggable strategies (Strategy pattern): Apple Foundation Models, Claude API, and a custom parser.
  • Post-workout structured journal — per-WOD score tracking (forTime / AMRAP / forLoad / completed), per-exercise weight & reps with set-by-set detail for strength workouts, scaling levels (Rx / Scaled / Rx+), PR flag.
  • Heart-rate zones with selectable formula — choose from Tanaka, Nes, Gulati, Fairbarn (sex-aware) or Classic. Per-workout snapshot freeze: your zones stay consistent even if you change the formula later.
  • Analytics & trends — training readiness score, heart-rate zone distribution, weight trend, training volume per category, per-exercise PR / 1RM analytics.
  • Manual entry escape hatch — re-attach a plan to a workout retroactively from History, useful when the live save flow misses (e.g., WatchConnectivity drops).
  • Health journal — weight, goals, HealthKit metrics, home-screen widgets and Live Activities for active workouts.

Screenshots

Drop the screenshot files into docs/screenshots/ using the names below and they'll render automatically.

Training Readiness — the first screen you see

The dashboard adapts to your daily recovery state. Two snapshots from the same week:

Low readiness day    High readiness day

Left: low-readiness day (RHR / HRV / sleep flagged red). Right: high-readiness day (full green across all metrics).

Stat drill-downs — any tile taps into a weekly detail

Every metric on the Today dashboard (HRV, sleep, activity, RHR, ...) opens its own detail screen with a weekly chart, score points, average and an explanation of what the metric means and how to act on it:

Sleep detail — weekly hours chart   Activity detail — weekly kcal chart   HRV detail — weekly ms chart

Same layout per metric: current value + status + score chip on top, weekly chart with average dashed line in the middle, contextual explanation on the bottom.

Analytics & trends

Analytics — volume + weight   Exercise balance per movement category

Training volume bars per workout category + weight trend line (left), exercise balance pie per movement type (right).

Workout journal

Activities list   Workout detail with HR chart   WOD plan detail

Workout history list, per-workout detail with heart-rate over time (color-coded by zone) + zone distribution, full WOD plan with warmup / WOD / cooldown and per-exercise scaling.

Live HR zones — real-time heart rate monitoring

During a workout the app streams heart rate in real time from either a paired BLE chest strap (Polar H10, Wahoo TICKR, etc. via HKLiveWorkoutDataSource) or Apple Watch (HKWorkoutSession mirroring channel — reliable even when WatchConnectivity is unreachable). The whole UI repaints to the current zone color so the athlete sees their intensity at a glance:

Resting zone (38% maxHR)   Fat Burning zone (65% maxHR)   Threshold zone (85% maxHR)   Anaerobic zone (95% maxHR)

Four representative tiers across the full spectrum — Resting (gray, 38%), Fat Burning (green, 65%), Threshold (orange, 85%) and Anaerobic (red, 95%). Live BPM, %maxHR, calories, session avg/max and elapsed time — all updated per HR sample, no polling.


🏋️ GymRoom — coach dashboard for group classes (iPad)

A trainer-facing iPad app for running group fitness classes — think a tablet on the gym wall.

  • Create & run group classes with class templates, schedule, and live monitoring.
  • Real-time heart-rate of every participant — one tile per athlete, color-coded by heart-rate zone, so the coach sees the whole room at a glance.
  • Join via QR + BLE peer-to-peer — a participant scans a QR code and streams heart rate to the iPad over Bluetooth, no cloud required (custom GATT protocol + peer identity handshake with reconnect grace).
  • Class history with charts — per-athlete HR ranges (BarMark per minute, color gradient by zone), donut for class-wide time-in-zones, calories distribution, long-press scrub with RuleMark + popup.
  • Connection robustness — BLE peer resume on reconnect (no duplicate athletes when someone runs outside class range), file logging exportable through the Files app.

Screenshots

Gym Room live with 4 athletes   Gym Room full class with QR code

HR over time — combined view   HR over time — per athlete   Time in zones stacked bar

Top: live class monitoring — one tile per athlete (left) and full class with QR pairing for new participants (right). Bottom: post-class analytics — combined HR over time, per-athlete BarMark ranges by minute, and stacked time-in-zones.


🏗️ Architecture

The two apps share a foundation of local Swift packages, so domain logic, models and services are reused across iPhone, iPad and Watch:

Package Responsibility
SharedModels Shared domain models, enums and constants (multi-platform)
HealthHub HealthKit, WatchConnectivity, Bluetooth, workout parsing, training calculations
AppDatabase SQLite persistence (SQLiteData) with CloudKit sync — users, sessions, exercise logs, HR snapshots
PeerMirror BLE peer-to-peer heart-rate streaming (host/peer, GATT, peer identity)
Commons Shared utilities, no external dependencies

Patterns & principles

  • TCA composition — reducers for all business logic, @Presents + Destination for navigation, @Shared(.appStorage) for persisted preferences, IdentifiedArrayOf
    • forEach for collections of child features.
  • Client / Service boundary — @DependencyClient structs as injectable boundary, Service (actor/class) as implementation hidden behind the client. Reuse via @Dependency(\.xxxClient).
  • Strategy pattern — pluggable algorithms (HR formulas, workout parsers, sex-aware variants) selected at runtime via enum + dispatch.
  • Snapshot pattern — per-workout HR formula freeze: snapshot table captures (maxHR, formula, age, sex) at workout-end so historical zones never shift when preferences change.
  • View Facade — SwiftUI views describe structure at the top (composition of named subviews), implementation at the bottom (private var / private func blocks). Makes diffs reviewable and snapshot-testable per section.
  • SOLID — single responsibility per reducer / per cell / per service, open-closed for extensions (e.g., adding a new HR formula = one struct + one enum case + one switch branch).
  • Swift 6 strict concurrency — Sendable everywhere, @Shared declared inside closures in TCA liveValue to avoid captured-var concurrency errors, AsyncStream multicast pattern for streams with multiple subscribers (view remount, TCA cancel).

🛠️ Tech stack

Language & platform: Swift 6.2 · iOS 26 / iPadOS 26 / watchOS 26 · Xcode 16+ (strict concurrency mode, defaultIsolation(MainActor.self)).

Apple frameworks: SwiftUI · HealthKit · WatchConnectivity · CoreBluetooth · WidgetKit · ActivityKit · Charts · Vision (OCR) · MapKit · CloudKit · App Intents.

Third-party (Point-Free): TCA (Composable Architecture) · SQLiteData · SwiftNavigation · Dependencies · Sharing · IdentifiedCollections · CasePaths · Perception · IssueReporting.

AI: Apple Foundation Models (on-device) · Anthropic Claude API (claude-sonnet-4-5).


About / Origins — how this project started

Inspired by Sean Allen's course, I decided to transform his application by adapting it to the TCA (The Composable Architecture) framework. The goal of this project is to gain a deep understanding of TCA by implementing modern design patterns and creating a modular, scalable application following best practices.

The results of my work and the details of each step can be found on GitHub: StepTrackerTCA. This project is not only a technical exercise but also an exploration of possibilities and best practices in the context of modern iOS app development.


📚 More

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages