Live Activities & Push Notifications
When implementing or fixing anything related to Live Activities (or push notifications generally), always check BOTH delivery flows — local push and remote push. They are handled by different code paths, so a field, behavior, or fix applied to one is easily missed in the other (e.g. a payload key parsed for APNs but dropped over local push, or alerting/sound handled differently per flow).
- Remote push (APNs / cloud): Home Assistant → the push relay (
Sources/PushServer) → APNs → the app /Sources/Extensions/NotificationService. The payload already carries ahomeassistantdictionary. - Local push (WebSocket /
NEAppPushProvider): delivered over the on-network channel and handled bySources/Extensions/PushProvider+Sources/Shared/Notifications/LocalPush(LocalPushManager,LocalPushEvent). The payload arrives as a flat{message, data}shape and is reshaped byLegacyNotificationParserImpl(Sources/SharedPush/Sources/NotificationParserLegacy.swift), which must explicitly promotedatafields intohomeassistant— any field not in that promotion list is silently dropped on this flow only.
Both flows converge on NotificationCommandManager → HandlerStartOrUpdateLiveActivity → LiveActivityRegistry (Sources/Shared/LiveActivity), with the UI rendered by Sources/Extensions/Widgets/LiveActivity.
Practical checklist when changing this area:
- If you add or read a notification/Live-Activity payload field, confirm it survives both the local-push parser promotion list and the remote-push payload.
- Verify alerting behavior (sound, haptics, banner suppression, the
silentflag) on both flows — local push presents notifications throughLocalPushManager, not the system directly. Sources/SharedPushis vendored as a separate copy underSources/PushServer/SharedPush(the relay). Keep the two parser copies in sync when a parsing change is relevant to both the app and the relay; some logic intentionally lives in only one copy (e.g. the Live Activitylive_updatepromotion is app-only, since the relay/cloud path already carries ahomeassistantdict). When you change one copy, decide explicitly whether the other needs the same change.- Add/extend tests for both flows (e.g.
Tests/Shared/LocalPushManager.test.swiftfor the local path,Sources/PushServer/Tests/SharedPushTestsfor the relay/parser).