From d8561b325d06799fb2e17036a3c70bdd31692c0a Mon Sep 17 00:00:00 2001 From: Andrew Blakeslee Moore Date: Sat, 4 Jul 2026 23:45:47 -0700 Subject: [PATCH] Live Activity Content Density Nucleic-Session: B3643133-163C-4C5D-BE20-1A6B7FB83DA9 Co-authored-by: Nucleic --- NucleicRemote/NucleicRemote/LiveActivityManager.swift | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/NucleicRemote/NucleicRemote/LiveActivityManager.swift b/NucleicRemote/NucleicRemote/LiveActivityManager.swift index 98f60a5..4052afa 100644 --- a/NucleicRemote/NucleicRemote/LiveActivityManager.swift +++ b/NucleicRemote/NucleicRemote/LiveActivityManager.swift @@ -17,6 +17,17 @@ final class LiveActivityManager { private var activity: Activity? + /// The last content we pushed. Updates that don't change it are skipped so we don't spend + /// ActivityKit's update budget on no-ops — `sync` fires on every host message (dashboard, + /// connectivity, pong, diff ticks…), most of which leave the aggregate identical. Burning the + /// budget on those is exactly what makes a *real* change land late and the glance read stale. + private var lastState: NucleicSessionAttributes.ContentState? + /// The newest state waiting to be applied, and the single task draining it. Coalescing to the + /// latest through one serial task means the newest data always wins — firing an unstructured + /// `Task` per `sync` let a later update lose a race to an earlier one and freeze the glance. + private var pendingState: NucleicSessionAttributes.ContentState? + private var updateTask: Task? + /// Reconcile the Activity with the current session set. func sync(hostName: String, sessions: [WireSessionSummary]) { guard ActivityAuthorizationInfo().areActivitiesEnabled else { return }