mcpField
A
alarmkit

alarmkit

github.com/dpearson2699开发1.2k3.6k 次安装13 周前更新
代码仓库

关于 alarmkit

面向 iOS 26+ / iPadOS 26+ 应用开发者的 AlarmKit 技能,用于安排指定时间的闹钟和倒计时计时器。内容涵盖授权、状态管理、贪睡行为,以及倒计时和暂停状态的 Live Activity 界面。

主要功能

  1. 01安排单次或每周重复闹钟
  2. 02按时长安排倒计时计时器
  3. 03管理暂停、恢复、停止和贪睡状态
  4. 04观察闹钟状态更新
  5. 05为倒计时和暂停状态配置 Widget 扩展

适用场景

  1. 01设置唤醒或定时提醒
  2. 02实现烹饪或训练间隔计时
  3. 03为重复闹钟处理暂停与贪睡
  4. 04在锁定屏幕和灵动岛呈现倒计时状态

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/dpearson2699/swift-ios-skills --skill alarmkit

安装后在 Claude Code 中输入/alarmkit确认已加载。

附带文件evals/evals.jsonreferences/alarmkit-patterns.md

详细介绍

AlarmKit

安排醒目的闹钟和倒计时计时器,响铃时会显示在锁定屏幕、灵动岛、待机模式以及配对的 Apple Watch 上。AlarmKit 需要 iOS 26+ / iPadOS 26+。闹钟可以突破专注模式和静音模式。

AlarmKit 的实时活动使用 ActivityKit 数据模型,但响铃提醒由系统管理,并非通用的自定义通知界面。自定义界面仅适用于倒计时和暂停的实时活动状态,这些状态由 Widget Extension 渲染,使用与安排闹钟时相同的 AlarmAttributes<Metadata> 和 AlarmPresentationState。

如需了解完整代码模式,包括授权、安排闹钟、倒计时计时器、稍后提醒处理和 Widget 设置,请参阅 references/alarmkit-patterns.md。

import AlarmKit

目录

工作流

1. 创建新闹钟或计时器
  1. 在 Info.plist 中添加 NSAlarmKitUsageDescription,并填写面向用户的说明。
  2. 在应用能够说明其价值时,使用 AlarmManager.shared.requestAuthorization() 请求授权,或者处理首次安排闹钟时出现的系统提示。
  3. 如果授权状态为 .denied 或不是 .authorized,应显示恢复界面,而不是安排闹钟。
  4. 配置 AlarmPresentation(提醒、倒计时和暂停状态)。
  5. 创建 AlarmAttributes,并设置展示、可选元数据和色调。
  6. 构建 AlarmManager.AlarmConfiguration(.alarm 或 .timer)。
  7. 使用 AlarmManager.shared.schedule(id:configuration:) 安排闹钟。
  8. 观察 alarmManager.alarmUpdates,并确认已安排的 ID 达到预期状态。
  9. 如果使用倒计时,请添加 Widget Extension 目标,并为相同的 AlarmAttributes<Metadata> 类型配置 ActivityConfiguration。
2. 检查现有闹钟代码

按照本文末尾的审核清单逐项检查。

授权

AlarmKit 需要用户授权。在应用能够说明其价值时尽早请求授权,或者让 AlarmKit 在首次安排闹钟时自动显示提示。如果用户在明确请求或自动提示后仍未授予授权,则不会安排闹钟,也不会响铃。

let manager = AlarmManager.shared

// Request authorization explicitly
let state = try await manager.requestAuthorization()
guard state == .authorized else { return }

// Check current state synchronously
let current = manager.authorizationState // .authorized, .denied, .notDetermined

// Observe authorization changes
for await state in manager.authorizationUpdates {
    switch state {
    case .authorized: print("Alarms enabled")
    case .denied:     print("Alarms disabled")
    case .notDetermined: break
    @unknown default: break
    }
}

闹钟与计时器的选择

功能闹钟(.alarm)计时器(.timer)
响铃时间指定时间(按计划)时长结束后
倒计时界面可选始终显示
重复是(每周的指定日期)否
使用场景起床、定时提醒烹饪、锻炼间歇

在指定时钟时间响铃时,使用 .alarm(schedule:...)。在从现在开始经过一段时间后响铃时,使用 .timer(duration:...)。

安排闹钟

Alarm.Schedule

一次性绝对日期使用 .fixed(date);本地时钟时间使用 .relative,并设置 .never 或 .weekly 重复。请查看重复闹钟模式,了解每日、工作日、周末和固定日期的变体。

安排与配置
let id = UUID()

let alert = AlarmPresentation.Alert(
    title: "Wake Up",
    secondaryButton: AlarmButton(
        text: "Snooze", textColor: .white, systemImageName: "bell.slash"
    ),
    secondaryButtonBehavior: .countdown
)
let presentation = AlarmPresentation(alert: alert)
struct EmptyAlarmMetadata: AlarmMetadata {}
let attributes = AlarmAttributes<EmptyAlarmMetadata>(
    presentation: presentation,
    metadata: nil,
    tintColor: .indigo
)

let snooze = Alarm.CountdownDuration(preAlert: nil, postAlert: 300)
let configuration = AlarmManager.AlarmConfiguration(
    countdownDuration: snooze,
    schedule: .relative(.init(
        time: .init(hour: 7, minute: 0),
        repeats: .never
    )),
    attributes: attributes,
    sound: .default
)

let alarm = try await AlarmManager.shared.schedule(
    id: id,
    configuration: configuration
)

如需了解包含授权检查的函数和带元数据的变体,请查看完整闹钟安排流程。

stopIntent 和 secondaryIntent 默认为 nil。若使用 AlarmKit 的标准系统停止行为,请省略 stopIntent;只有在停止时必须执行应用清理、自定义停止行为或其他副作用时才提供它。对于普通的稍后提醒/重复操作,如果使用 secondaryButtonBehavior: .countdown 和 Alarm.CountdownDuration.postAlert,请省略 secondaryIntent;只有在使用 .custom 次要行为,或需要应用清理/自定义行为时才提供它。

闹钟状态转换
cancel(id:)
    |
scheduled --> countdown --> alerting
    |             |             |
    |         pause(id:)    stop(id:) / countdown(id:)
    |             |
    |         paused ----> countdown (via resume(id:))
    |
cancel(id:) removes from system entirely
  • cancel(id:) -- 完全移除闹钟,包括重复闹钟
  • pause(id:) -- 暂停倒计时闹钟;处于其他状态时会抛出错误
  • resume(id:) -- 恢复已暂停的闹钟;处于其他状态时会抛出错误
  • stop(id:) -- 停止闹钟;一次性闹钟会被移除,重复闹钟会重新安排
  • countdown(id:) -- 从响铃状态重新开始倒计时(稍后提醒);处于其他状态时会抛出错误

倒计时计时器

计时器会在指定时长后触发,并始终显示倒计时 UI。使用 Alarm.CountdownDuration 控制提醒前和提醒后的时长。

CountdownDuration

Alarm.CountdownDuration 用于控制可见的倒计时阶段:

  • preAlert -- 闹钟触发前倒计时的秒数(主要倒计时)
  • postAlert -- 闹钟触发后重复提醒/稍后提醒倒计时的秒数

加载完整倒计时计时器流程, 了解计时器工厂、暂停/恢复界面、元数据和调度门控。

闹钟状态

每个 Alarm 都有一个 state 属性,用于反映其当前生命周期阶段。

状态含义
.scheduled已安排,并准备在适当的时间响铃
.countdown正在倒计时(计时器或提醒前阶段)
.paused倒计时已由用户或应用暂停
.alerting闹钟正在响铃——声音播放中,UI 显著显示
观察状态变化

AlarmManager.shared.alarms 是一个会抛出错误的 getter,用于获取当前守护进程快照。使用 try,并在依赖该快照前,选择传播错误或用 do/catch 包装启动时的刷新操作。

请观察 alarmUpdates,而不是维护独立的生命周期状态。加载 使用异步序列观察状态, 了解完整的存储和刷新循环。

从 alarmUpdates 中消失的闹钟不再由 AlarmKit 安排。如果需要区分已触发、 已取消和已重新安排的闹钟,请与应用持久化保存的 ID 进行比较。

AlarmAttributes 和 AlarmPresentation

AlarmAttributes 遵循 ActivityAttributes 协议,并定义闹钟实时活动的静态 数据。它是一个泛型类型,其 Metadata 类型需遵循 AlarmMetadata 协议;该协议继承 Decodable、Encodable、Hashable 和 Sendable。metadata 值本身是可选的,默认 为 nil。

AlarmPresentation 提供必需的响铃内容,以及可选的倒计时/暂停内容。系统会呈现响铃 UI; 小组件扩展可以使用相同的属性和呈现状态,自定义倒计时和暂停时的实时活动视图。请保持元数据轻量, 不需要时使用 nil,并与小组件扩展共享其类型。

AlarmPresentationState

AlarmPresentationState 是闹钟实时活动由系统管理的 ContentState。它包含闹钟 ID 和一个 Mode 枚举:

  • .alert(Alert) -- 闹钟正在响铃,包含预定时间
  • .countdown(Countdown) -- 正在倒计时,包含触发日期和时长
  • .paused(Paused) -- 倒计时已暂停,包含已用时长和总时长

对于非响铃状态,小组件扩展会读取 AlarmPresentationState.mode,以决定在灵动岛和锁定屏幕上 呈现哪种 UI。

AlarmButton

AlarmButton 定义闹钟操作的文本、颜色和符号。上面的代表性调度示例展示了标准的稍后提醒按钮。

次要按钮行为

响铃 UI 上的次要按钮有两种行为:

行为效果
.countdown使用 postAlert 时长重新开始倒计时(稍后提醒)
.custom触发 secondaryIntent(例如,打开应用)

实时活动集成

AlarmKit 闹钟响起时,会在锁定屏幕、灵动岛、待机显示以及已配对的 Apple Watch 上显示为实时活动。系统负责管理提醒界面。对于倒计时和暂停状态,请添加 Widget Extension 目标,其 ActivityConfiguration 使用与安排闹钟时相同的 AlarmAttributes<Metadata> 类型。

如果闹钟使用倒计时呈现方式,则需要 Widget Extension。请确保 App 和 Widget Extension 都能使用这种轻量级元数据类型。如果没有该扩展,闹钟可能会意外被关闭或无法提醒,不过在有限情况下(例如设备重启后首次解锁前),系统仍可能显示备用倒计时界面。

工作负责方
授权、调度/状态、呈现、声音、系统闹钟操作AlarmKit
主屏幕/Smart Stack 小组件、类型、时间线、重新加载widgetkit
非闹钟实时活动生命周期、令牌、远程内容状态activitykit
APNs、通知类别/操作、自定义通知界面push-notifications

AlarmKit 的提醒界面由系统在锁定屏幕、灵动岛、待机显示和已配对的 Apple Watch 上呈现;只有倒计时/暂停状态会使用 Widget Extension。

设置时,请使用 Apple 文档中列出的 NSAlarmKitUsageDescription 和 AlarmManager 授权。除非当前的 Apple 资料有说明,否则不要要求使用不受支持的 AlarmKit 设置键或 com.apple.developer.alarmkit。加载 闹钟的实时活动 Widget Extension,查看完整的共享属性小组件实现。

常见错误

错误修正方法
缺少使用说明字符串或授权门槛添加 NSAlarmKitUsageDescription;安排闹钟前处理拒绝授权的情况
使用计时器实现重复响铃使用带有 .weekly([...]) 的闹钟
App 自有状态取代 alarmUpdates观察系统序列,并按 ID 对账
为标准的停止/贪睡功能添加 Intents除非需要清理或自定义行为,否则不要添加
AlarmMetadata 负载过大使用轻量级元数据,或通过 ID 引用 App 数据
使用已弃用的 stopButton 初始化方法使用 init(title:secondaryButton:secondaryButtonBehavior:)

审查清单

  • 设置和授权门槛通过,且无需使用不受支持的权利键
  • 闹钟/计时器选择、呈现、元数据、Intents、贪睡时长和色调均有效
  • 保留已安排的 ID,并通过 alarmUpdates 对账;处理操作错误
  • 倒计时使用共享的 Widget Extension 属性和呈现状态
  • 系统管理的提醒界面及相邻技能的职责遵循路由表
  • 声音、振动、停止/贪睡和状态变更均通过设备端测试

参考资料

评论

支持 Markdown