Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Interval Timer (iOS + Web)

A lightweight interval training timer per the V1 PRD: configure work/rest durations and rounds, then run a color-coded, audio-cued workout loop.

Two versions live in this repo:

  • Native iOS app (IntervalTimer/) — requires a Mac with Xcode to install.
  • Progressive Web App (docs/) — same features, zero cost, no Mac needed. Host it on GitHub Pages, open it in Safari, and "Add to Home Screen".

Web app (PWA) — free hosting on GitHub Pages

The web version in docs/ is a dependency-free single-page app (plain HTML/JS, no build step) that ports the iOS app one-to-one: the same warmup → work/rest → finish state machine, wall-clock timing, synthesized audio cues, phase-colored full-screen UI, and last-used-settings persistence.

Hosting it

  1. On GitHub: Settings → Pages → Build and deployment → Source Deploy from a branch, branch main, folder /docs → Save.
  2. After a minute the app is live at https://<your-username>.github.io/interval-timer/.

To try it locally first: python3 -m http.server -d docs 8000 and open http://localhost:8000.

Installing on your iPhone

  1. Open the GitHub Pages URL in Safari (must be Safari, not Chrome).
  2. Tap the Share button → Add to Home ScreenAdd.
  3. Launch it from the home-screen icon — it opens full-screen with no browser chrome, works offline (service-worker cache), and never expires.

Web version limitations vs native

  • Audio needs a tap first: iOS only unlocks web audio after a user gesture — the Start button handles this, so cues just work.
  • Screen off / backgrounded: a web app cannot run in the background the way the native app's audio session can. The timer keeps the screen awake while running (Wake Lock API) and, if you do switch away, it fast-forwards to the correct phase when you come back — but cues won't sound while Safari is backgrounded, and there are no backup local notifications.
  • Silent switch: web audio respects the ringer switch on iOS; flip the ringer on (or use volume buttons) to hear cues.

Native iOS app

Requirements

  • A Mac with Xcode 16 or newer. iOS apps can only be compiled and installed onto an iPhone from macOS — this cannot be done from Linux/WSL.
  • An Apple ID (a free one works; no paid developer account needed).
  • iPhone 13 running iOS 17 or later, plus a USB cable for the first install.

Installing onto your iPhone 13

  1. Copy this whole folder to your Mac and open IntervalTimer.xcodeproj in Xcode.
  2. Select the IntervalTimer target → Signing & Capabilities tab:
    • Check Automatically manage signing.
    • Under Team, sign in with your Apple ID and select the personal team.
    • If Xcode complains the bundle ID is taken, change com.seantestapp.IntervalTimer to anything unique.
  3. On your iPhone: Settings → Privacy & Security → Developer Mode → On (the phone restarts). This toggle only appears after step 4's first connection on some iOS versions — connect first if you don't see it.
  4. Connect the iPhone via cable, unlock it, and tap Trust This Computer.
  5. In Xcode's toolbar device picker, choose your iPhone, then press Run (⌘R).
  6. First launch on-device: Settings → General → VPN & Device Management → trust your developer certificate, then open the app again.
  7. Allow notifications when prompted (used for background transition alerts).

Free Apple ID note: apps signed with a free personal team expire after 7 days — just press Run again to reinstall. A paid developer account extends this to a year.

Project layout

docs/                           Web app (PWA), served by GitHub Pages
  index.html                    Entire app: UI, state machine, engine, audio
  manifest.webmanifest          Install metadata (name, icons, standalone)
  sw.js                         Service worker: offline cache
  icon-180.png, icon-512.png    Home-screen icons
IntervalTimer/
  IntervalTimerApp.swift        App entry point
  Models/
    WorkoutConfiguration.swift  Work/rest/rounds + UserDefaults persistence
    WorkoutSession.swift        Pure phase state machine (UI-independent)
  Engine/
    WorkoutEngine.swift         Wall-clock countdown, cue timing, lifecycle
  Services/
    AudioCueService.swift       Synthesized tone cues via AVAudioEngine
    NotificationScheduler.swift Local-notification backup for background
  Views/
    ConfigurationView.swift     Setup screen
    DurationPicker.swift        Minutes/seconds wheel picker
    ActiveTimerView.swift       Full-screen workout UI
Info.plist                      Background audio mode, portrait-only, etc.

Behavior notes (native app)

  • Silent mode: the audio session uses the .playback category, so cues sound even with the ringer switch on silent. Background music (Spotify, Apple Music) is ducked for the duration of the workout, not stopped.
  • Background accuracy: timing is wall-clock based and the app keeps an active audio session (with the audio background mode) while a workout runs, so the countdown and cues continue with the screen off or the app minimized. Local notifications are also scheduled for every remaining transition as a backup, and cancelled when you return to the app.
  • Screen lock: auto-lock is disabled (isIdleTimerDisabled) only while a workout is running, and restored when it ends or you exit.
  • Halfway cue: the work-interval double-beep fires only on work intervals of 10 seconds or longer, so it never collides with the 3-2-1 countdown.
  • No rest after the final round — the last work interval goes straight to the finish chime.

About

PWA for an IOS based phone app for timing interval workouts.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages