All skills

AlarmKit integration for scheduling alarms and timers with custom UI, Live Activities, and snooze support. Use when implementing alarm or timer features in iOS 26+ apps.

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

This session only. Nothing lands on disk.

live-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

No alerts4mo3 checks · Risk SAFE
  • Gen Agent Trust Hub4mo

    No security issues detected. The skill provides documentation and code templates for integrating an iOS alarm framework with no malicious patterns or exfiltration risks identified.

  • Socket4mo

    No alerts

  • Snyk4mo

    Risk: LOW · No issues

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/alarmkit