Solo dev here. I just shipped a workout app built with Kotlin Multiplatform, and the part that fought me hardest was the watch tier — controlling a live workout session from the wrist (start/pause, next exercise, skip rest) on both Wear OS and watchOS, off one shared Kotlin core. A few things I learned that might save someone time:

1. The workout clock has to live on-device, not in the sync layer. My first version treated the phone as source of truth and let the watch mirror it. Bad idea — the moment BT dropped mid-set, the timer stalled. Fix: the session engine (rest timers, set state) runs locally and the phone/watch reconcile state deltas on reconnect, so the clock never depends on the link being up.

2. Live HR is a sampling problem, not a streaming one. Continuously observing the HR sensor stalled on some Samsung devices. I switched to polling at a fixed interval and bucketing samples — far more reliable across OEMs than the "observe" APIs.

3. Shared Kotlin core, thin native UI. Session logic, program/exercise models, and command validation are all in commonMain. The watch layers (Wear Compose / SwiftUI) are deliberately thin — they just emit commands into a shared executor that validates against live session state and echoes back. Kept the two platforms honest and cut the watch-specific bug surface a lot.

Questions for people who've shipped Wear OS:

  • How are you handling phone↔watch reconnection for a long-running foreground session? Data Layer vs. your own channel?
  • Any reliable pattern for keeping the watch app alive through a 60–90 min session without the OS reaping it?

Happy to go deeper on any of it. (App's live + free on both stores if it's useful to see it in action — I'll drop it in a comment rather than the post so this stays a dev discussion, not an ad.)

submitted by /u/AthleteWhoCodes
[link] [comments]