A running app designed by an ex-aircraft mechanic

Turn Every
Run Into A Flight.

An iOS running tracker built by a developer who used to maintain A320F aircraft.
Read your GPS, heart rate, and cadence like a flight instrument, and get pace deviations as GPWS-style warnings.

Download on the App StoreiOS 26+ · watchOS 11.5+SwiftUI · Actor · AsyncStreamAndroid port in progress
Flight Operations

Two Flight Modes

A state machine modeled after aircraft operating procedures runs the entire session.
Press start for a takeoff sequence, then a live instrument panel takes over for the run.

MODE A

Mission Flight

Set a target pace and distance, then fly the mission. GPWS warns you the moment you drift outside the allowed deviation.

  • Target pace ± deviation setting
  • Quick distance presets (3K / 5K / 10K / Half / Full)
  • MINIMUMS alert 50m before the target distance
MODE B

Free Flight

A VFR-style mode for running without a fixed goal. End the session manually with Touchdown.

  • No target set
  • GPWS disabled
  • Free-form pace logging
Ground Proximity Warning System
SINK RATE
Slower than target pace
OVERSPEED
Faster than target pace
MINIMUMS
50m before target distance
iPhone & Apple Watch

Two Screens, One Flight

Whether the Watch or the iPhone leads, both devices share the same FlightData.
Take a look at every real screen, from pre-flight checks to the post-landing log.

iPhone · scroll sideways
HOME · Dashboard
HOME · Dashboard
MISSION FLIGHT · Setup
MISSION FLIGHT · Setup
TAKEOFF · Pre-flight check
TAKEOFF · Pre-flight check
MISSION FLIGHT · CRUISE
MISSION FLIGHT · CRUISE
FREE FLIGHT · CRUISE
FREE FLIGHT · CRUISE
TOUCHDOWN
TOUCHDOWN
FLIGHT SUMMARY · Map route
FLIGHT SUMMARY · Map route
LOGBOOK
LOGBOOK
DATA BACKUP · CloudKit
DATA BACKUP · CloudKit
ALERTS · GPWS history
ALERTS · GPWS history
FLIGHT CALENDAR
FLIGHT CALENDAR
DYNAMIC ISLAND
DYNAMIC ISLAND
Apple Watch
WATCH · Mode select
WATCH · Mode select
WATCH · PFD
WATCH · PFD
WATCH · Summary
WATCH · Summary
Under The Hood

Four Design Decisions

Concurrency, state management, cross-device sync, and GPWS logic - the
four areas I thought hardest about while building RunWay.

CoreLocation
RunningCenter (actor · serial queue)
AsyncStream<FlightData>
HealthKit + WatchConnectivity
send / receive
ViewModel (@Observable) → SwiftUI
Why it's designed this way

GPS updates arrive continuously and require recalculating pace, distance, and GPWS status each time, so I isolated that calculation logic inside a RunningCenter Actor to guarantee state integrity. Heart rate and cadence come in through WatchConnectivity into a HealthCenter Actor that just holds the values thread-safely with no judgment logic of its own, and RunningCenter pulls from it whenever it needs those values for the @Observable ViewModel.

SwiftUIUI
@MainActor + @ObservableState management
RunningCenter (Actor)Concurrency
HealthCenter (Actor)Thread-safe heart rate/cadence storage
AsyncStreamSensors → ViewModel
FlightPhase enumState machine
WatchConnectivityiPhone ↔ Watch
SwiftDataStorage
CloudKit (CKRecord)Manual backup/restore · Private Database
Douglas-PeuckerGPS route compression, tolerance scaled to route diagonal
MapKit + MapPolylineRoute visualization
HealthKitHeart rate, cadence, workout session
WidgetKit + ActivityKitDynamic Island
WeatherKitLive weather
AVSpeechSynthesizerVoice announcements for km splits and countdown
CombineLocation, alert, session-state publishers + timer