← back to services

live · service

IntervalMate

인터벌 러닝 / 트레이닝 타이머. 워치 진동, Live Activity, 백그라운드 오디오 — 운동 중 화면을 보지 않아도 다음 신호가 손목과 귀로 도착합니다.

SwiftUI · MVVM WatchKit WidgetKit · Live Activity APNS Kotlin PHP MySQL

서비스 소개

IntervalMate 는 인터벌 러닝 / 인터벌 트레이닝을 하면서 — 화면을 보지 않고도 다음 단계로 넘어가는 순간을 정확히 알 수 있게 만드는 타이머입니다. 한 세션은 짧게는 20초, 길게는 30분 — 그 사이에서 사용자가 핸들 / 폰을 꺼내지 않고도 운동에 집중할 수 있도록 워치 진동, Live Activity, 백그라운드 오디오 신호를 한꺼번에 보냅니다.

iOS 앱은 SwiftUI + MVVM 으로 구현하고, Watch 앱과 Widget / Live Activity 익스텐션을 함께 묶어 한 번 시작하면 모든 표면에 동기화됩니다. 서버는 PHP 로 가볍게 짜고, APNS 푸시 / Live Activity 업데이트는 별도 sandbox / production 엔드포인트로 분기. 데이터(루틴 / 챌린지 / 워크아웃 로그 / 마일리지)는 MySQL 에 저장합니다. 서비스 자체는 다른 서버에서 운영 중이라 jiny.shop 도메인은 따로 두지 않았습니다.

Architecture

다른 서비스들과 달리 PHP 기반의 가벼운 서버를 별도 호스팅에서 운영합니다. APNS 와 Live Activity 푸시는 sandbox / production 엔드포인트를 분리해 호출.

/ client (Apple) iPhone app SwiftUI · MVVM Watch app WatchKit · 진동 Widget · Live Activity WidgetKit · ActivityKit https + APNS (sandbox / prod) / server (별도 호스팅) PHP API auth · routines · workouts · challenges · mileage · admin MySQL 루틴 · 챌린지 · 워크아웃 · 마일리지 APNS push + Live Activity 업데이트 / client (Android) Android app Kotlin · 기본 기능 (iOS 대비 후행 릴리즈)

Behind the scenes

만들면서 가장 힘 주었던 두 가지 — 화면을 보지 않게 만드는 일, 그리고 실제 운동 환경에서 정확히 동작하게 하는 일.

  1. 01

    화면을 보지 않게 만드는 일

    인터벌 타이머의 진짜 가치는 "사용자가 화면을 안 보게 만드는 데" 있습니다. 그래서 단계 전환을 알리는 신호를 세 곳에 동시에 띄웠습니다 — 워치 진동(WatchKit), 잠금화면 / 다이내믹 아일랜드(Live Activity), 그리고 백그라운드 오디오. 한 시점의 신호가 어느 하나라도 늦으면 사용자는 멈춰서 폰을 꺼내야 했고, 그게 운동 흐름을 끊어버렸습니다. 특히 Live Activity 는 한 번 설정하고 끝이 아니라 — 매 단계마다 ActivityKit 으로 갱신을 보내야 하고, 그 갱신이 누락되면 잠금화면의 시간이 멈춰 보입니다. "쌓이는 문제" / "업데이트 안 되는 버그" 같은 초기 커밋들은 모두 이 과정의 흔적입니다.

  2. 02

    백그라운드 카운트는 다른 게임이다

    앱이 활성 상태일 때는 단순한 Timer 한 개로 되는 일이, 백그라운드로 들어가는 순간부터 완전히 다른 문제가 됩니다. iOS 는 일정 시간 후 타이머를 멈추기 때문에 "절대 시각" 으로 만료 시점을 박아두고, 복귀 / 워치 깨우기 / 백그라운드 오디오 / APNS 알림 중 어느 경로로든 도착하게 만들어야 했습니다. 서버에서는 단계 전환 시점에 맞춰 무음 푸시를 쏘아 워치를 깨우는 방식까지 동원했고, sandbox / production APNS 의 차이로 디버그 단계에서 한참 헤맸습니다. "타이머 하나" 처럼 보이는 기능 뒤에 — 결국 모바일 OS 의 백그라운드 모델 전체와 정면으로 마주해야 한다는 걸 만들면서 배웠습니다.

Screenshots

카드를 누르면 큰 이미지로 볼 수 있습니다.

More

지나온 버전과 앞으로 들어갈 항목을 별도 페이지에서 확인할 수 있습니다.