A simple, single-user iOS app for tracking gym workouts and progress over time.
SwiftUI + SwiftData, iOS 17+. No login, automatic saving, optional light/dark
theme, and Markdown export.
| Settings |
Dark mode |
 |
 |
- Open
GymTracker.xcodeproj in Xcode (16 or newer).
- Select your iPhone (or a simulator) as the run destination.
- To run on your own device: select the GymTracker target → Signing &
Capabilities → set Team to your Apple ID. (Free Apple IDs work; the app
just needs re-signing every 7 days unless you have a paid developer account.)
- Press ⌘R.
- Today — opens automatically on today's date. Use the ‹ › arrows or the
calendar button to move to any past date and view or edit that session; a
Today button jumps back. Tap + to add an exercise, then add as many sets
as you like. One shared set of controls stays pinned at the top while the
exercises and their sets scroll below. Each set is a single tappable line; the
selected set (highlighted, across any exercise) is the one the pinned +/-
controls edit. The panel has quick-jump chips (20–120) so you can hit 80 in one
tap; the weight step (1 / 2.5 / 5 / 10 kg) is set in Settings. When the
selected set belongs to a bodyweight exercise the weight controls grey out and
only reps stay editable. New sets pre-fill from your last set, and a fresh
exercise pre-fills from the last time you did it. Use Add Warm-up (weighted
lifts only) for deliberately light warm-up sets: they're labelled "Warm-up"
(dashed outline), stay fully editable, but are excluded from every progress
metric so they never skew your numbers. Everything saves instantly — there is
no save button.
- Progress — pick an exercise to see your trend. Weighted lifts show an
estimated 1-rep max (Epley: weight × (1 + reps/30)), which folds weight and
reps into one strength number so progress is comparable even when reps vary, plus
top-weight and total-volume charts. Bodyweight movements show best-set reps and
total reps. Each headline shows the change since your first session.
- Exercises — add new movements, rename, reorder, delete, and toggle whether
an exercise tracks weight (off = reps only, for pull-ups / sit-ups).
- Settings & export — the gear (top-left of Today) opens Settings, where
you choose the appearance (System / Light / Dark) and the weight step. The
share button next to it exports your full history as a Markdown file with a
table per exercise per day — AirDrop it, save to Files, or send it anywhere.
- The 11 starting exercises are seeded on first launch. Bodyweight ones
(pull-ups, chin-ups, sit-ups, one-arm pull-up) track reps only; the rest track
weight. Toggle any of these in Exercises if you'd prefer otherwise.
- Each day is one session that can hold one or several exercises.
- Data lives on-device only.
GymTracker/
GymTrackerApp.swift App entry + SwiftData container
Models.swift Exercise / ExerciseLog / SetEntry + metrics
SeedData.swift First-launch default exercises
ContentView.swift Tab bar + appearance
TodayView.swift Today's session
ExerciseLogCard.swift Per-exercise logging card + set rows
Components.swift +/- controls, step picker, preset chips
ExercisesView.swift Manage exercises
AnalyticsView.swift Progress charts
SettingsView.swift Appearance + weight step
MarkdownExport.swift Export history as Markdown
PreviewData.swift Sample data for Xcode previews only