Ex-항공정비사가 설계한 러닝 앱
Turn Every
Run Into A Flight.
A320F 정비사 출신 개발자가 만든 iOS 러닝 트래커.
GPS, 심박수, 케이던스를 계기판처럼 읽고, 페이스 이탈을 GPWS 경보로 알려줍니다.
GLIDE PATH
MISSION FLIGHTCRUISE
PACE
5'12"
DIST
2.14km
HR
158bpm
CAD
172spm
FUEL
212kcal
Flight Operations
두 가지 비행 모드
항공기 운항 절차에서 착안한 상태 머신으로 러닝 전체를 관리합니다.
시작 버튼을 누르면 이륙 시퀀스가, 러닝 중에는 실시간 계기판이 기다립니다.
MODE A
Mission Flight
목표 페이스와 거리를 설정하고 운항합니다. 허용 오차를 벗어나면 GPWS가 즉시 경고합니다.
- 목표 페이스 ± 오차 설정
- 빠른 거리 선택 (3K / 5K / 10K / 하프 / 풀)
- 목표 거리 50m 전 MINIMUMS 경보
MODE B
Free Flight
목표 없이 자유롭게 달리는 VFR(시계비행) 모드. 수동으로 Touchdown하여 종료합니다.
- 목표 설정 없음
- GPWS 비활성
- 자유로운 페이스 기록
Ground Proximity Warning System
SINK RATE
목표 페이스보다 느려짐
OVERSPEED
목표 페이스보다 빨라짐
MINIMUMS
목표 거리 50m 전 진입
iPhone & Apple Watch
두 화면, 하나의 비행
Watch가 주도하든 iPhone이 주도하든, 두 기기는 같은 FlightData를 공유합니다.
이륙 준비부터 착륙 후 기록까지, 실제 화면으로 확인해보세요.
iPhone · 좌우로 스크롤












Apple Watch



Under The Hood
설계 결정 네 가지
동시성 처리, 상태 관리, 기기 간 동기화, GPWS 판정 로직 - RunWay를
만들며 가장 많이 고민한 네 가지 지점입니다.
CoreLocation
RunningCenter (actor · serial queue)
AsyncStream<FlightData>
HealthKit + WatchConnectivity
send / receiveViewModel (@Observable) → SwiftUI
왜 이렇게 설계했는가
“GPS 업데이트가 연속적으로 들어오면서 페이스, 거리, GPWS 판정까지 매번 계산해야 하므로, 이 계산 로직을 RunningCenter Actor로 격리해 상태 무결성을 보장했습니다. 심박수와 케이던스는 WatchConnectivity가 받아서 판정 로직 없이 값만 스레드 안전하게 들고 있는 HealthCenter Actor에 넘기고, RunningCenter가 필요할 때 그 값을 가져가 @Observable ViewModel로 전달합니다.”
SwiftUIUI
@MainActor + @Observable상태관리
RunningCenter (Actor)동시성
HealthCenter (Actor)심박수/케이던스 스레드 안전 보관
AsyncStream센서 → ViewModel
FlightPhase enum상태 머신
WatchConnectivityiPhone ↔ Watch
SwiftData저장
CloudKit (CKRecord)수동 백업/복원 · Private Database
Douglas-Peucker경로 대각선 비례 오차로 GPS 좌표 압축
MapKit + MapPolyline경로 시각화
HealthKit심박수·케이던스·운동 세션
WidgetKit + ActivityKitDynamic Island
WeatherKit실시간 날씨
AVSpeechSynthesizerkm 스플릿·카운트다운 음성 안내
Combine위치·알림·세션 상태 Publisher + Timer