GymTracker: how I published my first iOS app with SwiftUI and CoreData
How I designed, built and published GymTracker: a native iOS app with SwiftUI, CoreData, offline-first architecture and zero data collection.
GymTracker is the first application I designed, developed and published on the App Store as the sole person responsible for the product. It is a native iPhone app built with Swift, SwiftUI and CoreData to log workouts, track progressive overload and understand training progress without relying on spreadsheets, scattered notes or external services.
The short answer about the project is this: GymTracker turns the gym notebook into a fast, private and offline-first iOS experience. Users can create routines, record weight, repetitions and RPE, review their history and visualize metrics such as volume, estimated one-rep max, body weight and training consistency.
Project summary
| Area | Result |
|---|---|
| Problem | Logging and understanding strength progression without friction |
| Platform | Native iPhone application |
| My role | Sole designer and developer |
| Stack | Swift, SwiftUI, CoreData and Xcode |
| Architecture | MVVM with offline-first local persistence |
| Privacy | No data collected |
| Languages | Spanish and English |
| Status | Published for free on the App Store |
The public App Store listing identifies Gorka Hernandez Villalon as the developer, shows a 5.0 out of 5 rating from three ratings at the time of publishing this article and confirms that the application does not collect data.
The problem: recording data does not always make it useful
Logging sets during strength training is easy. Making those records useful several weeks later is harder. Progressive overload requires quick answers to practical questions:
- What weight and repetitions did I complete last time?
- Is my total volume increasing, or am I only accumulating sessions?
- How is my estimated one-rep max evolving?
- Am I training consistently?
- How does my body weight change alongside performance?
Many applications address this by adding more features, accounts, subscriptions and screens. My goal with GymTracker was the opposite: reduce the distance between finishing a set and saving a piece of data that can support the next decision.
The interface was designed for the real gym context: a dark theme, large buttons, fast logging and direct access to history. The app does not try to replace a coach or promise automatic results. Its job is to preserve useful information and return it clearly.
Designing the core flow first
Before thinking about charts or profiles, the critical flow was recording a set. If that action felt slow, no later visualization would compensate for the friction.
The product core revolves around three actions:
- Prepare a custom routine with the exercises and order each user needs.
- Log a session quickly by recording weight, repetitions and RPE.
- Review history and progression to decide how to approach the next workout.
This sequence also helped prioritize development. Every new feature had to improve at least one of those actions. The heatmap, for example, is not only a visual element: it makes consistency understandable at a glance. Volume and estimated one-rep-max charts turn isolated records into a trend.
SwiftUI for a native interface
Choosing SwiftUI allowed me to build the interface with declarative components and keep views connected to application state. For an app with forms, lists, histories, charts and different workout states, that relationship between data and UI is especially important.
The application follows an MVVM architecture. Separating views, presentation state and models prevents screens from accumulating all the logic. This matters when the same information appears in several places: one session affects history, charts and the heatmap, but every view should not need to reinterpret it independently.
SwiftUI also supports another project goal: GymTracker should feel like an iOS app rather than a website placed inside a phone. Navigation, controls and visual hierarchy follow patterns familiar to iPhone users.
CoreData and an offline-first architecture
GymTracker uses CoreData to store routines, exercises, sessions and metrics locally. This choice responds to two product requirements:
- the app must work at the gym even without network coverage;
- workout data does not need to leave the device to provide value.
In an offline-first architecture, local persistence is not a fallback. It is the main source of truth. Users can record and review information without waiting for an API or creating an account. That reduces dependencies, removes network latency and simplifies the experience.
The trade-off is that the data model matters greatly. Routines, exercises and records need consistent relationships so history and charts remain reliable. A saved set is not only one row: it feeds later calculations and becomes part of the user's training history.
Turning records into useful information
Saving data was only half of the problem. The other half was presenting it in a way that helps people interpret progress.
GymTracker includes:
- complete workout history;
- automatic total-volume charts;
- estimated one-rep-max progression;
- a profile with body-weight charts;
- a heatmap of completed sessions.
Each visualization answers a different time scale. History helps compare the current session with the previous one. Charts reveal trends. The heatmap summarizes consistency. Together, they move the experience from "I trained today" to "this is how my training is evolving."
Privacy as an architecture decision
Privacy was not added at the end as legal copy. It directly shaped the architecture: GymTracker stores information on the device and does not collect user data. This practice is publicly declared in its App Store listing.
Not requiring an account or sending workouts to a server has several benefits:
- fewer steps before using the app;
- full offline operation;
- less data exposure;
- no unnecessary remote infrastructure.
It also means accepting a limitation: a purely local architecture does not provide cross-device synchronization by default. For this project, I chose to prioritize simplicity, speed and privacy instead of building a cloud layer without a clear need.
Taking an independent app to the App Store
Publishing GymTracker changed the project. It stopped being an interface that worked in my environment and became a product other people could install, rate and use with their own data.
That step forces attention toward areas a prototype can hide:
- real compatibility across devices and iOS versions;
- copy and experience in Spanish and English;
- error handling outside the ideal path;
- a clear product description;
- privacy declarations;
- maintenance after the first release.
The published version introduced compatibility improvements, a profile with body-weight charts, a workout heatmap, fixes and Spanish and English support. That cycle taught me that launching is not finishing. It is the start of receiving real signals about what works.
What I built
I handled GymTracker end to end as its sole designer and developer:
- problem definition and scope;
- design of the main user flows;
- SwiftUI interface implementation;
- CoreData modeling and persistence;
- MVVM architecture;
- progress visualization;
- Spanish and English localization;
- App Store preparation and publication.
For me, this breadth is one of the project's most valuable aspects. It is not only about knowing Swift. It is about making connected decisions across product, experience, data, privacy and distribution.
What I learned
GymTracker left me with four main lessons:
- The speed of the primary action defines the product. At the gym, logging a set needs to feel almost immediate.
- Data needs context. History is useful; a visual trend helps people make decisions.
- Privacy can simplify a system. Collecting no data removes infrastructure and friction when the product does not need an account.
- Publishing raises the standard. Compatibility, languages, errors and maintenance become part of the technical work.
Result
The result is a public, free and verifiable iOS application that solves a specific problem with a focused architecture. GymTracker is available on the App Store, and its extended case study is available in the projects section of my portfolio.
GymTracker represents the kind of product I want to build: useful, focused software that can explain clearly why it exists. To discuss iOS development, SwiftUI or a mobile project, reach out through my contact page.