Skip to content

Sync playback progress locally between Apple Watch and phone on pause#4535

Open
dericleeyy wants to merge 5 commits into
trunkfrom
pcios-196-watch-playback-progress-sync
Open

Sync playback progress locally between Apple Watch and phone on pause#4535
dericleeyy wants to merge 5 commits into
trunkfrom
pcios-196-watch-playback-progress-sync

Conversation

@dericleeyy

@dericleeyy dericleeyy commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Fixes PCIOS-196

Playback progress made on the Apple Watch (Watch play source) didn't appear on the iPhone — and changes on the phone didn't appear on the watch — without manually tapping "Refresh now" on both devices, because the two apps only reconciled through a server sync/refresh.

Currently the Watch source only syncs to the cloud server, with a 2 minute throttle limit update. When the phone receives the update, it does not reflect it immediately and require an app restart. The idea now is for the watch to also send the update to the phone locally, without depending on cloud. The cloud sync is untouched.

On pause, each device now pushes its playback position directly to the other over WatchConnectivity and applies it to the local player/DB, so Now Playing and episode progress update without a manual refresh. Conflicts use last-write-wins on playedUpToModified, the actively-playing device is never overridden, and the existing server sync still propagates to other devices (web, iPad). Gated behind a new watchPlaybackProgressLocalSync feature flag (default on).

Changes

  • Add watchPlaybackProgressLocalSync feature flag (FeatureFlag.swift).
  • Add a PlaybackProgressUpdate WatchConnectivity message and a nowPlayingPlayedUpToModified now-playing key (WatchConstants.swift).
  • Watch → phone: on pause the watch sends its position (WatchSyncManager.playbackPausedSessionManager.sendPlaybackProgress); the phone applies it and moves the live mini-player via seekToFromSync (WatchManager.handlePlaybackProgressUpdate).
  • Phone → watch: the phone includes playedUpToModified in its now-playing state, and the watch applies the phone's paused position to its local player in SessionManager.handleStateUpdate (new WatchDataManager accessor).

To test

Use a paired iPhone + Apple Watch (or simulators) signed into the same Pocket Casts Plus account, with the watchPlaybackProgressLocalSync flag enabled.

Watch → phone:

  1. On the watch, set the play source to Watch and play an episode.
  2. Let it play ~15s, then pause on the watch.
  3. Open that episode / Now Playing on the phone without tapping Refresh.
  • Verify the phone shows the watch's position within a second or two.

Phone → watch:

  1. With the same episode loaded on the watch (Watch source), play it on the phone, then pause.
  • Verify the watch's Now Playing position updates to the phone's position without relaunching the watch app.

Flag off:

  • Verify that with the flag disabled, progress only syncs after a manual "Refresh now" (previous behavior).

Phone to Watch local sync

Screen.Recording.2026-06-17.at.12.07.06.AM.mov

Watch to Phone local sync

Screen.Recording.2026-06-16.at.11.31.32.PM.mov

Checklist

  • I have considered if this change warrants user-facing release notes and have added them to CHANGELOG.md if necessary.
  • I have considered adding unit tests for my changes.
  • I have updated (or requested that someone edit) the spreadsheet to reflect any new or changed analytics.

dericleeyy and others added 2 commits June 17, 2026 00:16
PCIOS-196: playback progress made via the Apple Watch (Watch play source)
did not appear on the phone — and the reverse — without manually tapping
"Refresh now" on both devices.

On pause, each device now pushes its playback position directly to the
other over WatchConnectivity and applies it to the local player/DB
(last-write-wins on playedUpToModified, skipping the actively-playing
device), so Now Playing/progress updates without a manual refresh. The
existing server sync still propagates to other devices. Gated behind the
new watchPlaybackProgressLocalSync feature flag (default on).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@dericleeyy dericleeyy marked this pull request as ready for review June 16, 2026 16:37
@dericleeyy dericleeyy requested a review from a team as a code owner June 16, 2026 16:37
@dericleeyy dericleeyy requested review from kean and removed request for a team June 16, 2026 16:37
@dericleeyy dericleeyy added this to the 8.15 milestone Jun 16, 2026
@dericleeyy dericleeyy added [Area] watchOS Issus related to watchOS [Area] Sync labels Jun 16, 2026
@dericleeyy dericleeyy self-assigned this Jun 16, 2026
@dericleeyy dericleeyy changed the title Sync playback progress between Apple Watch and phone on pause Sync playback progress locally between Apple Watch and phone on pause Jun 16, 2026
@kean kean requested a review from SergioEstevao June 16, 2026 21:40
@pocketcasts pocketcasts modified the milestones: 8.15, 8.16 Jun 23, 2026
@pocketcasts

Copy link
Copy Markdown
Contributor

Version 8.15 has now entered code-freeze, so the milestone of this PR has been updated to 8.16.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a WatchConnectivity “fast-path” to sync paused playback progress locally between Apple Watch and iPhone (in both directions), so Now Playing/progress updates without requiring a manual “Refresh now” or a server round-trip.

Changes:

  • Introduces a watchPlaybackProgressLocalSync feature flag (default on) to gate the behavior.
  • Adds a new WatchConnectivity message (PlaybackProgressUpdate) plus a new now-playing field (playedUpToModified) to support last-write-wins conflict resolution.
  • Implements watch→phone progress push on pause, and phone→watch progress application when the phone’s now-playing state updates.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
podcasts/WatchConstants.swift Adds message keys for playback progress updates and a now-playing playedUpToModified field key.
podcasts/Watch Communication/WatchManager.swift Receives/apply watch→phone progress updates and includes playedUpToModified in the phone→watch now-playing payload.
Pocket Casts Watch App/UI/WatchSyncManager.swift Sends watch→phone progress update on pause when the feature flag is enabled.
Pocket Casts Watch App/Data & Communication/WatchDataManager.swift Adds accessor for now-playing playedUpToModified from the phone-sent state.
Pocket Casts Watch App/Data & Communication/SessionManager+Send.swift Adds sendPlaybackProgress(...) message with guaranteed-delivery fallback.
Pocket Casts Watch App/Data & Communication/SessionManager.swift Applies phone→watch paused progress to the local watch player using playedUpToModified last-write-wins.
Modules/Sources/PocketCastsUtils/Feature Flags/FeatureFlag.swift Adds the watchPlaybackProgressLocalSync feature flag with default enabled.
CHANGELOG.md Adds release note entry for instant watch/phone progress sync on pause.

Comment thread podcasts/Watch Communication/WatchManager.swift Outdated

@SergioEstevao SergioEstevao left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested this today by installing the branch on my Watch and Phone.

[x] Update from Watch to Phone: where working correctly, when moving the position of the now play episode on the watch source and pausing after a couple of seconds the phone updated.

[x] Update from Phone to Watch: this didn't work for me. I move around the phone play position, paused. The Watch only updated when I force a refresh on the home screen on the watch.

dericleeyy and others added 2 commits June 25, 2026 00:13
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@dericleeyy dericleeyy requested a review from SergioEstevao June 25, 2026 06:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

[Area] Sync [Area] watchOS Issus related to watchOS

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants