All skills

SwiftUI framework skills — data flow (identity, Observation, state ownership), layout & containers (Layout protocol, lazy-stack performance), AlarmKit, 3D charts, rich text editing, customizable toolbars, and WebKit embedding. Use for SwiftUI state/rendering bugs, custom layouts, scroll performance, or these feature areas.

Use this Skill: https://skilld.dev/gh/rshankras/claude-code-apple-skills/swiftui

This session only. Nothing lands on disk.

alarmkitlive-activities.md

≈1.5k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Live Activities Integration

Displaying alarms and countdown timers on the Dynamic Island and Lock Screen using a widget extension.

Why You Need a Widget Extension

AlarmKit countdown and paused presentations appear on the Lock Screen and Dynamic Island through Live Activities. To render custom UI for these states, you must implement a widget extension with an ActivityConfiguration for AlarmAttributes.

Without the widget extension, the system cannot display countdown or paused presentations. Alert presentations work without a widget extension, but the countdown and paused states will not appear.

Setting Up the Widget Extension

1. Add a Widget Extension Target

In Xcode, add a new target: File > New > Target > Widget Extension. This creates a widget bundle where you add the alarm activity configuration.

2. Implement ActivityConfiguration

import WidgetKit
import SwiftUI
import AlarmKit

struct AlarmActivityWidget: Widget {
    var body: some WidgetConfiguration {
        ActivityConfiguration(for: AlarmAttributes.self) { context in
            // Lock Screen presentation
            AlarmLockScreenView(context: context)
        } dynamicIsland: { context in
            DynamicIsland {
                // Expanded region
                DynamicIslandExpandedRegion(.center) {
                    Text(context.attributes.presentation.title)
                        .font(.headline)
                }
                DynamicIslandExpandedRegion(.bottom) {
                    // Show countdown or paused state
                    AlarmExpandedView(context: context)
                }
            } compactLeading: {
                Image(systemName: "alarm.fill")
            } compactTrailing: {
                Text("Timer")
                    .font(.caption)
            } minimal: {
                Image(systemName: "alarm.fill")
            }
        }
    }
}

3. Register in Widget Bundle

@main
struct MyAppWidgets: WidgetBundle {
    var body: some Widget {
        // Your other widgets...
        AlarmActivityWidget()
    }
}

AlarmAttributes

AlarmAttributes is the type that conforms to ActivityAttributes and carries all the information needed to render alarm UI in Live Activities. AlarmKit provides this type -- you do not define it yourself.

Key properties available in the activity context:

  • Presentation information (title, buttons)
  • Metadata (if you conform to AlarmMetadata)
  • Tint color

Custom AlarmMetadata

To pass app-specific data to your widget extension, conform a type to the AlarmMetadata protocol. This allows you to include custom information that your Live Activity views can use.

import AlarmKit

struct MyAlarmMetadata: AlarmMetadata {
    let category: String
    let iconName: String
    let note: String
}

Use it when scheduling:

try await AlarmManager.shared.schedule(id: alarmID) {
    CountdownDuration(preAlert: 600, postAlert: 30)

    AlarmPresentation.Countdown(
        title: "Workout",
        pauseButton: AlarmButton(label: "Pause")
    )

    AlarmPresentation.Alert(
        title: "Workout Complete!",
        stopButton: AlarmButton(label: "Done")
    )

    AlarmPresentation.Paused(
        title: "Workout Paused",
        resumeButton: AlarmButton(label: "Resume")
    )

    MyAlarmMetadata(
        category: "fitness",
        iconName: "figure.run",
        note: "30-minute HIIT session"
    )

    AlarmAttributes(tintColor: .orange)
}

Lock Screen View Example

struct AlarmLockScreenView: View {
    let context: ActivityViewContext<AlarmAttributes>

    var body: some View {
        HStack {
            Image(systemName: "alarm.fill")
                .foregroundStyle(context.attributes.tintColor ?? .primary)

            VStack(alignment: .leading) {
                Text(context.attributes.presentation.title)
                    .font(.headline)
            }

            Spacer()
        }
        .padding()
    }
}

Common Patterns

Minimal Setup for Timer Apps

If you only need basic countdown display, the widget extension can be straightforward:

struct AlarmActivityWidget: Widget {
    var body: some WidgetConfiguration {
        ActivityConfiguration(for: AlarmAttributes.self) { context in
            // Lock Screen -- simple layout
            HStack {
                Image(systemName: "timer")
                Text(context.attributes.presentation.title)
                    .font(.headline)
                Spacer()
            }
            .padding()
        } dynamicIsland: { context in
            DynamicIsland {
                DynamicIslandExpandedRegion(.center) {
                    Text(context.attributes.presentation.title)
                }
            } compactLeading: {
                Image(systemName: "timer")
            } compactTrailing: {
                Text(context.attributes.presentation.title)
                    .font(.caption)
            } minimal: {
                Image(systemName: "timer")
            }
        }
    }
}

Anti-Patterns

// ❌ WRONG: Defining your own AlarmAttributes type
// AlarmKit provides AlarmAttributes -- do not create a custom struct with the same name
struct AlarmAttributes: ActivityAttributes {
    // ...
}
// ✅ Import AlarmKit and use the framework-provided AlarmAttributes

// ❌ WRONG: Using countdown presentations without a widget extension
// The countdown/paused UI simply will not appear
// ✅ Always add a widget extension with ActivityConfiguration(for: AlarmAttributes.self)

Checklist for Live Activities

  • Widget extension target added to the Xcode project
  • ActivityConfiguration(for: AlarmAttributes.self) implemented
  • Widget registered in the WidgetBundle
  • Lock Screen layout tested on real device
  • Dynamic Island compact, expanded, and minimal views implemented
  • Tint color applied via AlarmAttributes(tintColor:) if desired
  • Custom AlarmMetadata conformance if passing app-specific data

Source: SKILL.md on GitHub

1 warning2mo3 checks · Risk SAFE
  • Gen Agent Trust Hub2mo

    The skill provides comprehensive documentation and code examples for SwiftUI development, including data flow, layout, AlarmKit, 3D charts, rich text, and WebKit integration. No security issues or malicious patterns were detected.

  • Socket2mo

    No alerts

  • Snyk2mo

    Risk: MEDIUM · 1 issue

Signed by skilld at 32566aa. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 months ago.

Steadyupdated 3 months ago
What it can do
Reads files
last_verified
2026-07-16
review_by
2027-06-22
os_version
iOS 27 / macOS 27
All 3 allowed tools
ReadGlobGrep

README badge

README badge for rshankras/claude-code-apple-skills/swiftui