Skip to content

feat(ios): add Live Activity + Dynamic Island support#27488

Closed
leepokai wants to merge 3 commits intoopenclaw:mainfrom
leepokai:feat/ios-live-activity
Closed

feat(ios): add Live Activity + Dynamic Island support#27488
leepokai wants to merge 3 commits intoopenclaw:mainfrom
leepokai:feat/ios-live-activity

Conversation

@leepokai
Copy link
Copy Markdown

@leepokai leepokai commented Feb 26, 2026

Summary

  • Add ActivityWidget extension with Dynamic Island (compact/expanded) and Lock Screen banner views
  • LiveActivityManager singleton manages activity lifecycle with 1s debounce — shows thinking, streaming, tool execution, done, idle, and disconnected states
  • Idle state (gray) persists as long as the app is in background; disconnected state (red) shows when gateway connection drops
  • watchOS 11+ automatically mirrors iPhone Live Activities in Smart Stack — no watch code changes needed

Changes

New files

  • ActivityWidget/ — WidgetKit extension with Dynamic Island + Lock Screen views
  • Sources/LiveActivity/LiveActivityManager.swift — Activity lifecycle management
  • Sources/LiveActivity/OpenClawActivityAttributes.swift — Shared ActivityAttributes definition
  • Sources/LiveActivity/TaskSummaryService.swift — AI-powered task summary for activity titles

Modified files

  • project.yml — Added OpenClawActivityWidget target + NSSupportsLiveActivities
  • Config/Signing.xcconfig — Added OPENCLAW_ACTIVITY_WIDGET_BUNDLE_ID
  • Sources/Model/NodeAppModel.swift — Gateway event subscription for live activity updates
  • Sources/Info.plist — Added NSSupportsLiveActivities + alphabetized keys
  • Tests/Info.plist — Fixed indentation
  • SwiftSources.input.xcfilelist — Added new Swift source files

Test plan

  • Build with xcodegen generate && xcodebuild -scheme OpenClaw
  • Send a message — Live Activity appears on Dynamic Island + Lock Screen
  • Agent runs tools — steps increment, tool names update in Dynamic Island
  • Agent completes — "Done" state shown, transitions to "Idle" after delay
  • Background app — Live Activity persists showing "Idle" state
  • Disconnect gateway — Live Activity shows red "Disconnected" state
  • Reconnect gateway — transitions back to "Idle"
  • Pair Apple Watch (watchOS 11+) — Live Activity mirrors in Smart Stack

🤖 Generated with Claude Code

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Feb 26, 2026

Greptile Summary

Adds Live Activity support to the iOS app, enabling Dynamic Island and Lock Screen notifications that display real-time agent status updates. The implementation introduces a persistent activity that starts when the gateway connects and transitions through states (thinking, tool execution, streaming, done, idle, disconnected). Key features include 1s debounced updates for streaming content, on-device AI-powered task title generation, and comprehensive tool classification with friendly labels and SF Symbol icons.

The code integrates cleanly with the existing NodeAppModel by subscribing to operator gateway events and dispatching them to the LiveActivityManager singleton. The manager handles the full activity lifecycle with proper timer management, task cancellation, and memory safety using @MainActor isolation and weak references. The widget extension provides both Dynamic Island (compact/minimal/expanded) and Lock Screen banner views with appropriate visual states.

Architecture is sound with clear separation between the main app (LiveActivityManager), shared attributes (OpenClawActivityAttributes), and widget extension (OpenClawLiveActivity). The implementation follows Swift concurrency best practices and properly handles edge cases like activities being disabled, reconnection scenarios, and cleanup on disconnect.

Confidence Score: 5/5

  • This PR is safe to merge with high confidence - well-architected Live Activity implementation with proper concurrency handling and no critical issues
  • The implementation demonstrates excellent code quality with proper @MainActor isolation, weak reference usage to prevent retain cycles, comprehensive timer invalidation, and appropriate task cancellation. The integration with existing gateway event system is clean and non-invasive. No security vulnerabilities, memory leaks, or logical errors were identified. The feature is properly guarded with availability checks and handles disabled Live Activities gracefully.
  • No files require special attention - all files show consistent high quality implementation

Last reviewed commit: 2d4e77f

@leepokai leepokai force-pushed the feat/ios-live-activity branch 2 times, most recently from 47d2ac8 to 862e6ab Compare February 26, 2026 19:16
leepokai and others added 3 commits March 1, 2026 16:21
Show agent progress on Lock Screen and Dynamic Island while app is
backgrounded. States: thinking, streaming, tool execution, done, idle,
and disconnected.

- ActivityWidget extension with compact/expanded Dynamic Island views
  and Lock Screen banner
- LiveActivityManager singleton with 1s debounce and idle persistence
- Disconnected state (red) vs idle state (gray) for gateway status
- watchOS 11+ automatically mirrors via Smart Stack (no watch changes)

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Show orange "Connecting..." in Dynamic Island and Lock Screen while
the gateway is establishing a connection. Transitions to gray "Idle"
once connected. Previously the activity started directly in Idle state
even while still connecting.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
- End duplicate activities from previous app launches on init and
  before starting a new one (fixes multiple Dynamic Islands)
- Idle (connected, no AI running): green dot + green text
- Connecting: gray dot + gray text + spinner

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@leepokai leepokai force-pushed the feat/ios-live-activity branch 2 times, most recently from 9dc7233 to a3dc8ef Compare March 1, 2026 19:54
mbelinky added a commit that referenced this pull request Mar 3, 2026
Add lock-screen/Dynamic Island connection health states and prune duplicate/stale activities before reuse. This intentionally excludes AI/title generation and heavier UX rewrites from #27488.

Co-authored-by: leepokai <[email protected]>
mbelinky added a commit that referenced this pull request Mar 4, 2026
* feat(ios): add live activity connection status and cleanup

Add lock-screen/Dynamic Island connection health states and prune duplicate/stale activities before reuse. This intentionally excludes AI/title generation and heavier UX rewrites from #27488.

Co-authored-by: leepokai <[email protected]>

* fix(ios): treat ended live activities as inactive

* chore(changelog): add PR reference and author thanks

---------

Co-authored-by: leepokai <[email protected]>
@mbelinky
Copy link
Copy Markdown
Contributor

mbelinky commented Mar 4, 2026

Closing as superseded by the focused replacement in #33591, which carries forward the two approved improvements from this PR (Live Activity connection status + stale/duplicate cleanup) with attribution retained. Thanks again @leepokai for the original implementation direction.