关于 alarmkit
面向 iOS 26+ / iPadOS 26+ 应用开发者的 AlarmKit 技能,用于安排指定时间的闹钟和倒计时计时器。内容涵盖授权、状态管理、贪睡行为,以及倒计时和暂停状态的 Live Activity 界面。
主要功能
- 01安排单次或每周重复闹钟
- 02按时长安排倒计时计时器
- 03管理暂停、恢复、停止和贪睡状态
- 04观察闹钟状态更新
- 05为倒计时和暂停状态配置 Widget 扩展
适用场景
- 01设置唤醒或定时提醒
- 02实现烹饪或训练间隔计时
- 03为重复闹钟处理暂停与贪睡
- 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
目录
- 工作流
- 授权
- 闹钟与计时器的选择
- 安排闹钟
- 倒计时计时器
- 闹钟状态
- AlarmAttributes 和 AlarmPresentation
- AlarmButton
- 实时活动集成
- 常见错误
- 审核清单
- 参考资料
工作流
1. 创建新闹钟或计时器
- 在 Info.plist 中添加
NSAlarmKitUsageDescription,并填写面向用户的说明。 - 在应用能够说明其价值时,使用
AlarmManager.shared.requestAuthorization()请求授权,或者处理首次安排闹钟时出现的系统提示。 - 如果授权状态为
.denied或不是.authorized,应显示恢复界面,而不是安排闹钟。 - 配置
AlarmPresentation(提醒、倒计时和暂停状态)。 - 创建
AlarmAttributes,并设置展示、可选元数据和色调。 - 构建
AlarmManager.AlarmConfiguration(.alarm 或 .timer)。 - 使用
AlarmManager.shared.schedule(id:configuration:)安排闹钟。 - 观察
alarmManager.alarmUpdates,并确认已安排的 ID 达到预期状态。 - 如果使用倒计时,请添加 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 属性和呈现状态
- 系统管理的提醒界面及相邻技能的职责遵循路由表
- 声音、振动、停止/贪睡和状态变更均通过设备端测试
参考资料
- 模式和代码:references/alarmkit-patterns.md
- Apple 文档:AlarmKit | AlarmManager | AlarmAttributes | 安排闹钟