---
name: ios-widget-live-activity
description: "WidgetKit, Live Activities, Dynamic Island, ActivityKit — the surfaces that drive app re-engagement. Scaffolds widgets, lock-screen Live Activities, and Dynamic Island regions. Handles ActivityKit background updates and push token flow."
license: MIT
---

# iOS Widget & Live Activity Builder

Scaffolds the engagement surfaces that live outside your app: Home Screen and Lock Screen widgets, Lock Screen Live Activities, and Dynamic Island presentations. It wires up the WidgetKit and ActivityKit boilerplate — the widget extension target, the `TimelineProvider`, the `ActivityAttributes`, and the push-token plumbing — so you can focus on the layout and data rather than the ceremony. Built for iOS engineers shipping order-tracking, ride, delivery, sports, or workout features.

## When to use it

- You're adding a Home Screen widget and don't want to hand-write a `TimelineProvider`, `TimelineEntry`, and `WidgetConfiguration` from scratch.
- You need a Live Activity that shows live progress (delivery ETA, game score, timer) on the Lock Screen and in the Dynamic Island.
- You want server-driven updates to a running activity via ActivityKit push tokens instead of polling.
- You're migrating a `StaticConfiguration` widget to `AppIntentConfiguration` for user-editable widgets on iOS 17+.

## What it does

The skill generates a Widget Extension target and the matching Swift files:

- A `Widget` conforming type with either `StaticConfiguration` or `AppIntentConfiguration`, plus `supportedFamilies` (e.g. `.systemSmall`, `.accessoryRectangular`, `.accessoryCircular`).
- A `TimelineProvider` (or `AppIntentTimelineProvider`) implementing `placeholder`, `snapshot`, and `timeline` with a chosen `TimelineReloadPolicy` (`.atEnd`, `.after`, `.never`).
- An `ActivityAttributes` struct with its nested `ContentState`, plus the `ActivityConfiguration` that renders the Lock Screen view and the `DynamicIsland { ... }` regions: `expanded` (`DynamicIslandExpandedRegion` for `.leading`, `.trailing`, `.center`, `.bottom`), `compactLeading`, `compactTrailing`, and `minimal`.
- ActivityKit lifecycle: `Activity.request(...)`, `activity.update(...)`, `activity.end(...)`, and observing `Activity.pushToken` / `pushTokenUpdates` to forward tokens to your server for APNs `liveactivity` pushes.

It also sets the required `Info.plist` keys (`NSSupportsLiveActivities`, `NSSupportsLiveActivitiesFrequentUpdates`) and shares data through an App Group.

## Usage example

```bash
curl -fsSL --create-dirs -o ~/.claude/skills/ios-widget-live-activity/SKILL.md https://claudeskil.com/skills/ios-widget-live-activity/SKILL.md

# then, in your project:
claude "scaffold a Live Activity for delivery tracking with an
ETA and progress bar, plus Dynamic Island compact + expanded views"
```

Starting an activity from the app:

```swift
let attributes = DeliveryAttributes(orderID: "A17")
let state = DeliveryAttributes.ContentState(eta: .now.addingTimeInterval(900), progress: 0.4)
let activity = try Activity.request(
    attributes: attributes,
    content: .init(state: state, staleDate: nil),
    pushType: .token
)
```

## Tips & gotchas

- Live Activities only run on a physical device with iOS 16.1+; the simulator won't show the Dynamic Island reliably.
- `ContentState` must be `Codable` and small — APNs payloads for activity pushes are capped (~4KB).
- Frequent push updates require the `NSSupportsLiveActivitiesFrequentUpdates` key and are still budgeted by the system; design for throttling.
- Widgets and the app must share an App Group, or `WidgetCenter.shared.reloadTimelines(ofKind:)` will read empty data.

## FAQ

**Does it support interactive widgets?** Yes — it can wire up `AppIntent` buttons and toggles (iOS 17+) inside the widget body.

**Can I update an activity without a server?** Yes, call `activity.update(...)` locally, but background updates while the app is suspended need APNs push tokens.

**Which iOS version?** WidgetKit needs iOS 14; Live Activities need 16.1; Dynamic Island APIs target iPhone 14 Pro and later.
