HomeCase studiesA Sprint Interval Training App with a...

Case study · Berlin, Germany

A Sprint Interval Training App with a Smartwatch Companion

Health and fitness — athletic conditioning and interval training

Interval training needs two things a stopwatch cannot give you: a start you cannot anticipate, and a record of every individual effort rather than one long blur. Our team built a mobile training application that acts as an electronic starter — running a structured start sequence with an unpredictable hold before the signal — then records each repetition individually, with heart rate, distance and pace captured on the wrist through a companion smartwatch application. Offline-first by design, with subscription access and a training history that reconciles work recorded on either device. Delivered as two native mobile applications over a REST API, replacing an earlier cross-platform prototype.

Industry
Health and fitness — athletic conditioning and interval training
Solution
Consumer mobile application with a paired smartwatch companion, a REST API and a small administrative back office, monetised through auto-renewing subscriptions.
Platforms
Android · iOS · Cross-platform · Web & API
Stack
Laravel · PHP · React Native · MySQL · MariaDB · Java
Location
Berlin, Germany · delivered remotely
Role
Engineering, with the team behind for mobile and QA

Delivered remotely for a business based in Berlin, Germany. Names withheld by agreement.

Project Overview

Industry: Health and fitness — athletic conditioning and interval training.

Type of solution: Consumer mobile application with a paired smartwatch companion, a REST API and a small administrative back office, monetised through auto-renewing subscriptions.

Business context: Interval training — short maximum efforts separated by measured recovery — is one of the most effective and least well-supported forms of training on a phone. General fitness applications record a session as one continuous activity, which is exactly the wrong shape for work that consists of eight separate efforts with recovery between them. And the athlete training alone has no credible way to start: pressing your own button means you know when the effort begins, which changes the effort.

General users: Individual athletes training alone or in small groups, on a field, a track or a treadmill, using a phone or a paired smartwatch.

General purpose: To replace the coach with the whistle and the notebook with a structured record — giving a solo athlete an unpredictable start signal and a per-repetition training history without having to operate a device mid-effort.

The Business Challenge

A start you can anticipate is not a start. If the athlete triggers their own countdown, they know when the signal is coming and pre-empt it. The start has to carry a genuine element of unpredictability, the way a real race start does, or the effort being measured is not the effort that matters.

Timing has to be honest. The effort is timed from the signal, not from a button press, and the audio has to fire when it says it does. In a product whose entire value is measurement, a few hundred milliseconds of drift is not a rounding error — it is the difference between a useful record and a discouraging one.

The interesting data is per-repetition. An interval session is not one activity. It is a sequence of efforts, each with its own duration, distance, speed, peak heart rate and recovery. Recording it as a single continuous workout throws away everything the athlete actually wants to look at.

Training happens where the network does not. Fields, tracks, trails and gyms are exactly the places where connectivity is worst. The application has to be completely functional with no network at all, and reconcile afterwards without losing or duplicating anything.

The phone is not on the athlete. Mid-session, the handset is on the ground at the side of the track. Anything the athlete needs to see or control during the effort has to be on their wrist — which means the wearable has to be able to run the whole session by itself, not act as a remote display.

Two devices, one training history. If either device can start a session, both produce records, and both sets have to merge into one coherent history without duplicates and without ambiguity about where a given effort came from.

Metrics require the health platform, and the health platform requires native code. Live heart rate, distance and energy during a workout, written back into the user's own health record, are available only through the mobile platform's own health frameworks and its wearable workout session — which set a hard floor on the technology choice.

Access has to work offline too. Subscription entitlement cannot be checked over the network at the moment the athlete starts training, and it cannot be checked at all by a wrist device that has no connectivity of its own.

Our Approach

Rebuild natively, for a stated reason. The product began as a cross-platform prototype that proved the interaction: a countdown, the audio cues, the hold, the signal. It could not do the things the product needed next — a smartwatch application running a real health workout session, live heart-rate collection, wrist complications, platform in-app purchase. Rather than fight the boundary, we rebuilt as two native applications with a shared API contract behind them. The prototype earned its keep by settling the interaction design cheaply; the rewrite was a deliberate decision taken once the product's requirements were known, not a preference.

Keep everything that matters off the network. The countdown, the randomised hold, the audio cues, the timing and the metric collection are entirely local. Nothing in the workout path makes a network call. The server is an account store and a history sink, consulted before and after training and never during it.

Make the wearable a peer, not a screen. The watch application runs its own start sequence, its own timers and its own health workout session, collecting heart rate, energy and distance through the platform's live workout data as the effort happens. It records complete repetitions independently and hands them to the handset when the two are in range. The athlete can leave the phone in a bag and train from the wrist alone.

Record provenance on every repetition. Each recorded effort carries a marker identifying which device produced it. That single field is what makes a merged two-device history trustworthy — and what makes it debuggable when it is not.

Treat the local store as authoritative. Repetitions are written to an on-device database as they complete, each flagged as not yet uploaded. A reconciliation pass batches everything outstanding, sends it in one request, and writes the server's identifiers back onto the local rows. If the upload never happens, the athlete still has their session.

Give the app, the extension and the watch one source of truth. Settings and subscription entitlement live in a single shared container that all three read, rather than three copies that drift apart. Entitlement is mirrored to the wearable over the device sync channel, so a watch with no connectivity of its own still knows where it stands.

Buffer what the wrist cannot send. The watch queues its own analytics events and hands them to the handset, which forwards them and then restores its own context — so wearable usage is measurable without the wearable needing to reach anything itself.

Record the audio for the device it plays on. Cue and signal assets were produced separately for handset and wrist playback, with alternative voice options, because a cue that carries across a field from a phone speaker is not the same recording that works six inches from the ear.

Ship it like a bigger product than it is. Staged deployments with rollback, environment-specific builds mapping to separate development, staging and production backends, and a continuous integration pipeline that deploys, migrates and restarts — on a project small enough that most teams would have deployed by hand.

The Solution

Electronic start sequence. A configurable countdown leads into a structured verbal start sequence, followed by a deliberately unpredictable hold and then the start signal. The athlete cannot pre-empt it, which is the entire point.

Selectable signal and voice. The start signal can be a whistle or a spoken cue, with alternative voice options, and assets recorded specifically for handset or wrist playback.

Two training modes. A distance-based mode and a repetition-based sprint mode, each with its own start behaviour and its own recording shape.

Per-repetition recording. Every effort is recorded individually: duration, recovery interval, distance, speed, heart rate, energy, the hold interval that preceded it, and a series of samples taken through the effort.

Independent smartwatch application. A full companion application — start, timer, rest, summary and settings — running its own health workout session so that live metrics are collected by the platform during the effort, with wrist complications for quick access.

Health platform integration. Heart rate, distance and energy are read under the platform's own permission model, and completed workouts are written back into the user's device health record so the training appears alongside everything else they do.

Two-device reconciliation. Sessions started on either device merge into a single history, each repetition tagged with its origin, with no duplication.

Offline-first history. All work is stored on-device first and uploaded in batches when connectivity allows, with server identifiers reconciled back onto local records.

Training history and charts. A calendar history rolling up by year, month and day with totals, drilling into individual sessions and repetitions, with graphed session statistics.

Guided onboarding. An introductory walkthrough, a profile step capturing the attributes used for metric estimation, and an interactive tutorial that lets the user experience the start sequence before their first real session.

Subscription access. Auto-renewing subscription terms with an introductory period, receipt handling and restore, and entitlement state persisted to the account so it follows the user to their other devices — including the wrist.

Administrative back office. User administration with role-based staff accounts, account status control, and spreadsheet export of the user base.

Key Features

Unpredictable start sequence A structured verbal countdown followed by a randomised hold before the start signal, so the athlete cannot anticipate the start — with a fixed-interval alternative for training that calls for it.

Per-repetition training record Each effort recorded individually with its own duration, recovery, distance, speed, heart rate and energy, plus sampled data through the effort — the shape interval training actually has.

Independent smartwatch workout A companion application that runs the full session on the wrist, recording a real platform health workout with live metric collection, so the handset can stay in the bag.

Device-origin provenance on every record Every repetition is tagged with the device that produced it, which is what makes a merged two-device history reliable rather than approximate.

Offline-first recording with batch reconciliation Sessions are written to a local database as they happen and uploaded in batches afterwards, with server identifiers written back — so training in a dead zone loses nothing.

Single shared settings and entitlement store App, extension and wearable read one container for configuration and subscription state, so all three agree, including when the wearable is offline.

Health platform read and write Live heart rate, distance and energy read during the session under explicit user permission, and completed workouts written back to the user's own health record.

Device-appropriate audio Separate cue and signal recordings for handset and wrist playback with alternative voices, because the same audio does not work at both distances.

Calendar training history with charts Year, month and day roll-ups with totals, drilling down to individual repetitions, with graphed statistics.

Subscription entitlement that follows the user Receipt handling with restore, entitlement persisted to the account and mirrored to the paired wearable.

Technical Architecture

Mobile clients. Two natively written applications sharing one API contract. The primary client is built in Swift with a storyboard-driven interface, an on-device relational store for session records, a charting layer for history, and a paired wearable extension. The second client is a native Java application covering the core start sequence and account journeys, built with environment-specific flavours mapping to separate backends.

Wearable layer. A companion application and extension running the platform's own workout session and live workout data builder, so heart rate, distance and energy are collected by the operating system during the effort and delivered as callbacks that fold into per-repetition statistics. Complications and a notification path complete the wrist experience.

Device sync layer. A bidirectional connectivity manager treating handset and wearable as peers: application context for settings and entitlement, interactive messaging for live exchange, and a queued transfer path for completed repetitions and buffered analytics. Both directions are implemented, because either device can originate a session.

Local persistence layer. An on-device relational store holding every repetition with a synchronisation flag, plus a shared app-group container holding settings and entitlement readable by the application, its extension and the wearable.

Synchronisation layer. A reconciliation pass that selects unsynchronised records, uploads them in one batch, and writes returned identifiers back onto local rows. Fetching history from the server also triggers an upload of anything still outstanding, so the two directions self-heal.

API layer. A token-authenticated REST API providing authentication, batch session upload, calendar-aggregated history retrieval, session deletion, per-user settings and subscription state, alongside a session-authenticated administrative back office and a web password-reset flow serving the mobile journey.

Authentication layer. OAuth2 bearer tokens with a client-side token manager that coalesces concurrent refresh attempts into a single request and schedules renewal ahead of expiry.

Data layer. A relational database holding accounts, per-user settings, subscription state and session records, with history aggregation computed per request.

Delivery. Staged deployment automation with linked environment and key files and rollback support, driven by a continuous integration pipeline that deploys, migrates, clears cache and restarts the runtime.

Flow: Start sequence and timing (local) → per-repetition records written to the on-device store → wearable health session metrics merged in over the device sync channel → batch upload to the token-authenticated API → aggregated training history returned → charts and calendar history rendered locally

Technology Stack

Category Technology
Backend language PHP
Backend framework Laravel
Database MySQL / MariaDB
API authentication OAuth2 bearer tokens (Laravel Passport)
Back office Server-rendered administrative interface with role-based staff accounts
Reporting Spreadsheet export
Deployment Capistrano staged deployment with rollback
CI/CD CircleCI pipeline running deploy, migration, cache clear and service restart
Primary mobile platform Swift, UIKit, storyboard-driven interface
Local persistence Core Data session store with per-record sync flag
Shared storage App group container for settings and entitlement
Wearable WatchKit application and extension with complications
Health data HealthKit, with workout session and live workout data builder on the wearable
Device sync WatchConnectivity (application context, messaging, queued transfer)
Subscriptions StoreKit auto-renewing subscriptions with restore
Mobile networking Alamofire
Charting Native charting library for history graphs
Second mobile platform Java, AndroidX, Retrofit 2 with OkHttp
Build environments Product flavours mapping to development, staging and production backends
Audio Platform audio playback with device-specific cue and signal assets
Analytics Firebase Analytics on both platforms, with wearable events relayed via the handset
Superseded prototype React Native with Redux and local device storage

Technical Challenges & Solutions

Challenge Our Approach
A start the athlete can anticipate invalidates the effort being measured A structured verbal sequence followed by a randomised hold before the signal, so the start carries genuine unpredictability, with a fixed-interval alternative available for training that requires one.
Timing and audio must be accurate, with no network in the path The entire workout path — countdown, hold, cues, signal, timing, metric collection — runs locally on the device. No network call occurs during a session; the server is consulted only before and after.
Interval training does not fit a single-activity data model A per-repetition record carrying its own duration, recovery, distance, speed, heart rate, energy and sampled data through the effort, with the session as a grouping rather than the unit of record.
The phone is not on the athlete during the effort A companion wearable application that runs the complete session independently, driving the platform's own health workout session so live metrics are collected by the operating system on the wrist.
Either device can start a session, and both histories must merge A bidirectional device sync layer treating the two as peers, with an origin marker written onto every repetition so merged history is unambiguous and duplicates are detectable.
Training happens where connectivity does not An offline-first local store with a per-record synchronisation flag, batch upload of everything outstanding, and server identifiers reconciled back onto local rows — with history retrieval also triggering an upload so the two directions self-heal.
Subscription state must be known by a wearable with no connectivity Entitlement persisted centrally, cached in a container shared by the application, its extension and the wearable, and mirrored over the device sync channel so all three agree without a network call.
Wearable usage could not be measured directly Analytics events queued on the wrist and relayed through the handset, which forwards them and then restores its own context — giving visibility into wearable behaviour without the wearable reaching anything itself.
A cross-platform prototype could not reach the platform capabilities the product needed A deliberate native rebuild once requirements were known — smartwatch health sessions, live heart-rate collection, complications and platform in-app purchase all sit below the cross-platform boundary — with the prototype having already settled the interaction design at low cost.

Security & Reliability

Token-based authentication. OAuth2 bearer tokens issued by the framework's first-party OAuth implementation, with a client-side token manager that renews ahead of expiry and coalesces concurrent refresh attempts into one request rather than a burst.

Per-user data scoping. Every session query, aggregation and deletion is bound to the authenticated user's identity server-side, so a user's training history is reachable only by that user.

Separation of audiences. The administrative back office authenticates through a separate session-based guard from the token-authenticated mobile API, with role-differentiated staff accounts.

Explicit health data consent. Heart rate, distance and energy are read only under the mobile platform's own permission model, with the user granting each category explicitly and able to revoke it at any time. Completed workouts are written back into the user's own device health record.

Data durability under poor connectivity. Session records are written locally the moment a repetition completes and are not considered transferable until the server confirms them, so an interrupted upload or an absent network never costs the athlete their training.

Reconciliation that self-corrects. Because history retrieval also triggers upload of anything outstanding, a device that failed to sync recovers on the next successful fetch rather than requiring intervention.

Provenance on every record. The device-origin marker on each repetition provides an audit trail through a two-device system, making merged history verifiable rather than merely plausible.

Staged releases with rollback. Deployment automation with environment and key files linked outside the release directory, so a bad release can be reverted without touching configuration or credentials.

Scalability & Performance

Nothing on the critical path is remote. The timing-sensitive work — countdown, hold randomisation, audio, effort timing, metric capture — is entirely local. Server latency, connectivity and load cannot affect the accuracy of a workout, which is the property this product cannot compromise.

Batched, deferred upload. Session records accumulate locally and upload in a single batch afterwards. Server load is therefore proportional to sessions completed rather than to efforts performed, and arrives after the training rather than during it.

Platform-driven metric collection. On the wearable, heart rate, energy and distance arrive through the operating system's live workout data mechanism rather than being polled — the difference between a session that lasts a training block and one that drains the battery.

Local rendering of history. Calendar history and charts render from the on-device store, with the server consulted to backfill rather than to serve every view.

Stateless application tier. Token authentication and externalised configuration keep the application server free of per-user state, so instances are replaceable and releases are reversible.

Environment-separated backends. Development, staging and production builds address separate backends by construction rather than by configuration flag, so load testing and pre-release verification never touch live data.

Business Outcomes

  • A solo athlete gets a credible start, with an unpredictable hold before the signal, without needing a second person with a whistle.
  • Training is recorded at the level it actually happens, per repetition rather than as one undifferentiated session.
  • The wrist is enough. A complete session can be run, timed and recorded from the wearable, with the handset left at the side of the field.
  • Physiological data comes from the platform, with heart rate, distance and energy collected during the effort and written back to the user's own health record.
  • Training in a dead zone loses nothing, because the device records first and reconciles later.
  • One coherent history across two devices, with every effort traceable to the device that recorded it.
  • Subscription access works where the network does not, because entitlement is cached in a container all three components read.
  • A prototype proved the concept cheaply before the investment, and the native rebuild that followed was scoped against known requirements rather than assumptions.

Why it worked

Fitness applications look simple and are not. The simplicity is the product: a countdown, a signal, a number. Everything difficult sits underneath — timing that has to be honest, a wearable that has to run a real workout session rather than mirror a screen, two devices that both produce data and must agree afterwards, and a network you cannot assume exists at the moment the user needs the app most.

Our team builds for that. We kept every millisecond-sensitive path local, because a training app that depends on a server is a training app that is wrong outdoors. We made the wearable a full participant rather than a display, because that is where the user actually is. We put an origin marker on every record, because a two-device history that cannot explain itself is a support burden waiting to happen. And when the cross-platform prototype ran out of road at the platform boundary, we said so and rebuilt natively — which is a more useful thing to tell a client than a workaround.

Our teams work across native iOS and Android, wearable and health platform integration, offline-first synchronisation, in-app subscription and entitlement, and Laravel API development — with the judgement to know which parts of a product must be exact and which can be approximate.

Final Summary

Interval training is one of the most demanding things to support well on a phone, for reasons that have nothing to do with how the app looks. The athlete cannot start themselves without anticipating the start. The interesting data is per-effort, not per-session. The phone is on the ground, not in the hand. The connectivity is poor precisely where the training happens. And the physiological measurements that make the record worth keeping are only reachable through the platform's own health frameworks and a wearable workout session.

Our team built an application that addresses each of those directly. A structured start sequence with a genuinely unpredictable hold before the signal replaces the coach with the whistle. Every repetition is recorded individually, with its duration, recovery, distance, speed, heart rate and energy. A companion smartwatch application runs the whole session on the wrist, driving a real platform health workout so metrics are collected by the operating system as the effort happens, and written back into the user's own health record afterwards. Work recorded on either device merges into one history, each effort tagged with its origin.

Underneath sits the part users never see: an offline-first local store where nothing is considered transferred until the server confirms it, a batch reconciliation that self-heals on the next successful fetch, a single shared container so the app, its extension and the wearable agree about settings and subscription entitlement even with no network, and staged deployment automation with rollback on a product small enough that most teams would deploy by hand. The application began as a cross-platform prototype that settled the interaction cheaply and was rebuilt natively when the product's requirements moved below the cross-platform boundary — a decision made deliberately, at the right time, for reasons that were written down.

01 — Questions

asked about this kind of project

When is it right to rebuild a cross-platform app natively?

When the requirements move below the cross-platform boundary and stay there. A wearable running a real health workout session, live heart-rate collection during an effort, watch complications and platform in-app purchase are not things you bridge around — they are the product. The honest test is whether the native capability is central or peripheral. If it is central, rebuild and say why. If it is peripheral, a native module is cheaper than a rewrite. The prototype in this project was not wasted: it settled the interaction design at a fraction of the cost of settling it natively.

How do you build an offline-first mobile app that does not lose data?

Make the local store authoritative, not a cache. Records are written on device the moment they exist, each carrying a flag saying whether the server has confirmed them. Upload is a batch of everything outstanding, and the server's identifiers are written back onto local rows afterwards. The detail that matters most is making the *fetch* path also trigger an upload, so a device that failed to sync recovers on its next successful read rather than needing anyone to notice.

How should a smartwatch companion app be designed?

Decide first whether it is a display or a participant. A display mirrors the phone and is straightforward. A participant runs the session itself, records its own data and syncs back — which is what you need when the phone is not on the user. The participant model costs considerably more: bidirectional sync, an origin marker on every record so merged history is unambiguous, and a shared container so both sides agree about settings and entitlement. Choose deliberately, because retrofitting the second model onto the first is close to a rewrite.

How do you keep timing accurate in a fitness app?

Keep everything timing-sensitive local and never put a network call in the path. Audio cues, countdowns and effort timing must run on device with no dependency on a server. Time the effort from the signal rather than from the user's input, and let the platform's own workout session collect physiological metrics rather than polling for them — it is more accurate and dramatically kinder to the battery.

How do you handle subscription entitlement across paired devices?

Persist the entitlement centrally so it follows the account, cache it in a container that every component reads, and mirror it to the paired device over the device sync channel. The requirement people underestimate is offline: a wrist device with no connectivity of its own still has to know whether the user is entitled, which rules out checking at the point of use. Verification of the underlying purchase belongs on the server, not on the client.

Why does per-repetition data matter more than session totals?

Because the athlete's question is never "how long did I train". It is "was the fifth one slower than the first, and did I recover before the sixth". Recording an interval session as a single continuous activity — the default in most fitness applications — discards exactly the structure that makes the session worth analysing. Modelling the repetition as the unit of record, with the session as a grouping, changes what the product can tell the user.

What should a backend do in a device-first mobile product?

Less than teams expect. Where the intelligence genuinely belongs on the device — timing, sensors, offline operation — the server's job is to hold accounts, receive batched history, aggregate it for retrieval and stay out of the critical path. Pushing logic server-side in that situation adds latency and a failure mode without adding capability. The discipline is deciding this deliberately rather than by default.

What is usually underestimated in a health and fitness app?

Everything that is not the workout screen. Permission flows for health data, entitlement that has to work offline, reconciliation between devices, audio that has to be legible at different distances on different hardware, and history views that have to make sense across time zones when the user travels. The timer is the easy part, and it is the part everyone plans for.

03 — Similar project?

describe what is different about yours

Build yours.

Tell me what exists, what you need and the deadline. Fixed price for a defined scope, or hourly from $10 with a written estimate first.

Ahmedabad, India · IST (UTC+5:30) · --:-- IST · Mon–Fri 09:00–18:00 IST · US & EU overlap daily

No newsletter, no CRM. Just a reply.