AlarmManager (闹钟) PRO
AlarmManager (iOS 26+) 是 Scripting 提供的全局 API,用于创建和管理基于 AlarmKit 的闹钟、定时器和倒计时提醒。它不需要导入,可直接在脚本中使用。
这个 API 适合以下场景:
- 创建一次性闹钟,例如“今晚 22:30 提醒我”
- 创建每天或每周重复的闹钟
- 创建番茄钟、运动计时器、倒计时等短时提醒
- 自定义提醒界面的标题、按钮、颜色、图标和元数据
- 结合
AppIntent 让提醒界面的按钮触发脚本逻辑
- 监听闹钟状态变化并同步更新 UI
使用前提
建议在使用前先判断当前环境是否支持 AlarmKit:
if (!AlarmManager.isAvailable) {
console.log("当前系统不支持 AlarmKit")
}
如果当前设备或系统版本不支持,相关方法可能无法正常工作。
基本概念
AlarmManager 主要围绕以下对象工作:
Alarm:已存在的闹钟实例
Schedule:触发时间规则
Countdown:倒计时参数
Button:提醒界面按钮样式
Sound:提醒声音
AlertPresentation:提醒触发时的展示内容
CountdownPresentation:倒计时进行中的展示内容
PausedPresentation:倒计时暂停时的展示内容
Attributes:提醒界面的整体展示属性
Configuration:最终用于创建闹钟、定时器、倒计时的配置对象
Alarm ID 规则
创建闹钟时传入的 id 必须使用:
生成。
不要手动拼接固定字符串,也不要复用旧 ID。每次创建新的闹钟、定时器或倒计时时,都应生成一个新的 UUID 字符串。
正确示例:
不推荐:
const id = "morning-alarm"
const id = `timer-${Date.now()}`
后续对闹钟的 cancel、stop、pause、resume、startCountdown 等操作,都需要使用创建时对应的同一个 ID。
AlarmState
type AlarmState = "scheduled" | "countdown" | "paused" | "alerting"
表示闹钟当前状态。
"scheduled"
表示闹钟已创建,处于等待触发状态。
常见于:
"countdown"
表示当前处于倒计时进行中。
常见于:
"paused"
表示当前倒计时已暂停。
"alerting"
表示提醒已经触发,当前处于提醒展示或响铃状态。
type SecondaryButtonBehavior = "countdown" | "custom"
控制提醒界面第二按钮的行为方式。
"countdown"
第二按钮用于启动一个倒计时行为。
通常适合“稍后提醒我”“再过几分钟提醒一次”这类场景。
"custom"
第二按钮作为自定义按钮存在,实际行为由 secondaryIntent 决定。
AlarmAppIntent
type AlarmAppIntent = AppIntent<any, AppIntentProtocol.LiveActivityIntent>
表示可绑定到闹钟按钮上的 AppIntent。
它主要用于:
- 停止按钮触发额外业务逻辑
- 次要按钮触发自定义动作
- 与 Live Activity、Widget、ControlWidget 等机制联动
可配置的位置包括:
Configuration.alarm(...).stopIntent
Configuration.alarm(...).secondaryIntent
Configuration.timer(...).stopIntent
Configuration.timer(...).secondaryIntent
Configuration.countdown(...).stopIntent
Configuration.countdown(...).secondaryIntent
注意这里要求的 AppIntent 协议类型是:
AppIntentProtocol.LiveActivityIntent
也就是说,给 AlarmManager 绑定的意图应当使用 LiveActivityIntent 协议注册。
后文有完整示例。
AlarmUpdateListener
type AlarmUpdateListener = (alarms: Alarm[]) => void
用于监听闹钟列表变化的回调函数。
当闹钟被创建、取消、暂停、恢复、开始倒计时或状态发生变化时,监听器会收到最新的 Alarm[]。
Alarm
class Alarm {
readonly id: string
readonly state: AlarmState
readonly schedule?: Schedule | null
readonly countdownDuration?: Countdown | null
}
表示一个已存在的闹钟对象。
id
闹钟唯一标识符。
创建闹钟时必须使用 UUID.string() 生成,后续取消、停止、暂停、恢复等操作都依赖这个值。
state
readonly state: AlarmState
当前闹钟的状态。
schedule
readonly schedule?: Schedule | null
闹钟的时间规则。
纯定时器场景下不一定有 schedule。
countdownDuration
readonly countdownDuration?: Countdown | null
倒计时相关配置。
Schedule
class Schedule {
readonly type: "fixed" | "relative"
readonly date?: Date | null
readonly hour?: number | null
readonly minute?: number | null
readonly weekdays?: number[] | null
static fixed(date: Date): Schedule
static relative(hour: number, minute: number): Schedule
static weekly(hour: number, minute: number, weekdays: number[]): Schedule
}
用于描述闹钟的触发时间规则。
type
readonly type: "fixed" | "relative"
表示时间规则类型。
"fixed":固定绝对时间
"relative":按小时和分钟规则安排
date
readonly date?: Date | null
固定时间闹钟的具体触发时间。
hour
readonly hour?: number | null
触发小时。
minute
readonly minute?: number | null
触发分钟。
weekdays
readonly weekdays?: number[] | null
每周重复触发的星期数组。
具体 weekday 的编号语义以你的底层实现为准。通常会使用 1 到 7 表示一周中的某几天。
Schedule.fixed(date)
static fixed(date: Date): Schedule
创建一个固定时间触发的日程。
const schedule = AlarmManager.Schedule.fixed(
new Date("2026-03-20T22:30:00")
)
Schedule.relative(hour, minute)
static relative(hour: number, minute: number): Schedule
创建一个按时分安排的规则。
通常适合“每天某个时间”的提醒。
const schedule = AlarmManager.Schedule.relative(7, 30)
Schedule.weekly(hour, minute, weekdays)
static weekly(hour: number, minute: number, weekdays: number[]): Schedule
创建一个每周重复的提醒规则。
const schedule = AlarmManager.Schedule.weekly(8, 0, [2, 3, 4, 5, 6])
Countdown
class Countdown {
readonly preAlert?: number | null
readonly postAlert?: number | null
static create(options?: {
preAlert?: DurationInSeconds | null
postAlert?: DurationInSeconds | null
}): Countdown
}
用于定义倒计时相关参数。
preAlert
readonly preAlert?: number | null
提醒前的倒计时时长,单位为秒。
postAlert
readonly postAlert?: number | null
提醒后的附加时长,单位为秒。
具体行为取决于底层实现。
Countdown.create(options?)
static create(options?: {
preAlert?: DurationInSeconds | null
postAlert?: DurationInSeconds | null
}): Countdown
创建倒计时配置对象。
const countdown = AlarmManager.Countdown.create({
preAlert: 10 * 60,
postAlert: 5 * 60
})
class Button {
static create(options: {
title?: string
textColor?: Color
systemImageName?: string
}): Button
}
用于定义提醒界面按钮样式。
参数
title
按钮标题。
textColor
按钮文字颜色。
文档中的 Color 建议使用十六进制字符串形式,例如:
"#ffffff"
"#ff9500"
"#34c759"
systemImageName
SF Symbols 图标名称。
static create(options: {
title?: string
textColor?: Color
systemImageName?: string
}): Button
const stopButton = AlarmManager.Button.create({
title: "停止",
textColor: "#ffffff",
systemImageName: "stop.fill"
})
const snoozeButton = AlarmManager.Button.create({
title: "稍后",
textColor: "#ffffff",
systemImageName: "timer"
})
Sound
class Sound {
static default(): Sound
static named(name: string): Sound
}
用于定义提醒声音。
Sound.default()
使用系统默认声音。
const sound = AlarmManager.Sound.default()
Sound.named(name)
static named(name: string): Sound
使用指定名称的声音。
const sound = AlarmManager.Sound.named("bell")
可用名称取决于你的底层实现与系统支持情况。
AlertPresentation
class AlertPresentation {
static create(options: {
title: string
stopButton?: Button | null
secondaryButton?: Button | null
secondaryBehavior?: SecondaryButtonBehavior | null
}): AlertPresentation
}
用于定义提醒触发时的展示内容。
参数
title
提醒标题,必填。
已废弃。 从 iOS 26.1 起,提醒响起时的停止按钮由系统以 slider 形式渲染,不再使用自定义按钮。stopButton 仅为向后兼容保留,在 iOS 26.1+ 会被忽略,可以不填。
停止按钮样式(仅 iOS 26.0 回退使用)。
第二按钮样式。
secondaryBehavior
第二按钮行为,可选值:
AlertPresentation.create(options)
static create(options: {
title: string
stopButton?: Button | null
secondaryButton?: Button | null
secondaryBehavior?: SecondaryButtonBehavior | null
}): AlertPresentation
const alert = AlarmManager.AlertPresentation.create({
title: "起床时间到了",
stopButton: AlarmManager.Button.create({
title: "关闭",
textColor: "#ffffff",
systemImageName: "xmark"
}),
secondaryButton: AlarmManager.Button.create({
title: "稍后提醒",
textColor: "#ffffff",
systemImageName: "timer"
}),
secondaryBehavior: "countdown"
})
CountdownPresentation
class CountdownPresentation {
static create(title?: string | null, pauseButton?: Button | null): CountdownPresentation
}
用于定义倒计时进行中的展示内容。
static create(title?: string | null, pauseButton?: Button | null): CountdownPresentation
const countdownPresentation = AlarmManager.CountdownPresentation.create(
"专注计时中",
AlarmManager.Button.create({
title: "暂停",
textColor: "#ffffff",
systemImageName: "pause.fill"
})
)
PausedPresentation
class PausedPresentation {
static create(title?: string | null, resumeButton?: Button | null): PausedPresentation | null
}
用于定义倒计时暂停时的展示内容。
static create(title?: string | null, resumeButton?: Button | null): PausedPresentation | null
const pausedPresentation = AlarmManager.PausedPresentation.create(
"已暂停",
AlarmManager.Button.create({
title: "继续",
textColor: "#ffffff",
systemImageName: "play.fill"
})
)
Attributes
class Attributes {
static create(options: {
alert: AlertPresentation
countdown?: CountdownPresentation | null
paused?: PausedPresentation | null
tintColor?: Color
metadata?: Record<string, string>
}): Attributes | null
}
用于组合提醒界面的完整展示属性。
参数
alert
提醒触发时的展示内容,必填。
countdown
倒计时状态的展示内容。
paused
暂停状态的展示内容。
tintColor
整体强调色,建议使用十六进制字符串:
"#ffffff"
"#007aff"
"#ff9500"
附加元数据,可用于记录业务信息。
Attributes.create(options)
static create(options: {
alert: AlertPresentation
countdown?: CountdownPresentation | null
paused?: PausedPresentation | null
tintColor?: Color
metadata?: Record<string, string>
}): Attributes | null
const attributes = AlarmManager.Attributes.create({
alert: AlarmManager.AlertPresentation.create({
title: "番茄钟结束",
stopButton: AlarmManager.Button.create({
title: "完成",
textColor: "#ffffff",
systemImageName: "checkmark"
})
}),
countdown: AlarmManager.CountdownPresentation.create(
"专注中",
AlarmManager.Button.create({
title: "暂停",
textColor: "#ffffff",
systemImageName: "pause.fill"
})
),
paused: AlarmManager.PausedPresentation.create(
"已暂停",
AlarmManager.Button.create({
title: "继续",
textColor: "#ffffff",
systemImageName: "play.fill"
})
),
tintColor: "#ff9500",
metadata: {
type: "pomodoro",
source: "study-script"
}
})
Configuration
class Configuration {
static alarm(options: {
schedule?: Schedule | null
attributes: Attributes
sound?: Sound | null
stopIntent?: AlarmAppIntent | null
secondaryIntent?: AlarmAppIntent | null
}): Configuration | null
static timer(options: {
duration: DurationInSeconds
attributes: Attributes
sound?: Sound | null
stopIntent?: AlarmAppIntent | null
secondaryIntent?: AlarmAppIntent | null
}): Configuration | null
static countdown(options: {
countdown?: Countdown | null
schedule?: Schedule | null
attributes: Attributes
sound?: Sound | null
stopIntent?: AlarmAppIntent | null
secondaryIntent?: AlarmAppIntent | null
}): Configuration | null
}
用于生成最终可传给 AlarmManager.schedule() 的配置对象。
Configuration.alarm
static alarm(options: {
schedule?: Schedule | null
attributes: Attributes
sound?: Sound | null
stopIntent?: AlarmAppIntent | null
secondaryIntent?: AlarmAppIntent | null
}): Configuration | null
创建普通闹钟配置。
适合:
参数
schedule
触发时间规则。
attributes
提醒展示属性,必填。
sound
提醒声音。
stopIntent
停止按钮绑定的 AppIntent。
secondaryIntent
第二按钮绑定的 AppIntent。
示例
const schedule = AlarmManager.Schedule.fixed(
new Date("2026-03-20T07:30:00")
)
const attributes = AlarmManager.Attributes.create({
alert: AlarmManager.AlertPresentation.create({
title: "早安,起床了",
stopButton: AlarmManager.Button.create({
title: "关闭",
textColor: "#ffffff",
systemImageName: "xmark"
}),
secondaryButton: AlarmManager.Button.create({
title: "稍后",
textColor: "#ffffff",
systemImageName: "timer"
}),
secondaryBehavior: "countdown"
}),
tintColor: "#34c759",
metadata: {
category: "morning"
}
})
const configuration = AlarmManager.Configuration.alarm({
schedule,
attributes,
sound: AlarmManager.Sound.default()
})
Configuration.timer
static timer(options: {
duration: DurationInSeconds
attributes: Attributes
sound?: Sound | null
stopIntent?: AlarmAppIntent | null
secondaryIntent?: AlarmAppIntent | null
}): Configuration | null
创建定时器配置。
适合:
参数
duration
定时器总时长,单位秒。
attributes
展示属性,必填。
sound
提醒声音。
stopIntent
停止动作绑定的 AppIntent。
secondaryIntent
第二按钮动作绑定的 AppIntent。
示例
const attributes = AlarmManager.Attributes.create({
alert: AlarmManager.AlertPresentation.create({
title: "25分钟专注结束",
stopButton: AlarmManager.Button.create({
title: "完成",
textColor: "#ffffff",
systemImageName: "checkmark"
})
}),
countdown: AlarmManager.CountdownPresentation.create(
"专注中",
AlarmManager.Button.create({
title: "暂停",
textColor: "#ffffff",
systemImageName: "pause.fill"
})
),
paused: AlarmManager.PausedPresentation.create(
"暂停中",
AlarmManager.Button.create({
title: "继续",
textColor: "#ffffff",
systemImageName: "play.fill"
})
),
tintColor: "#ff9500",
metadata: {
mode: "focus"
}
})
const configuration = AlarmManager.Configuration.timer({
duration: 25 * 60,
attributes,
sound: AlarmManager.Sound.default()
})
Configuration.countdown
static countdown(options: {
countdown?: Countdown | null
schedule?: Schedule | null
attributes: Attributes
sound?: Sound | null
stopIntent?: AlarmAppIntent | null
secondaryIntent?: AlarmAppIntent | null
}): Configuration | null
创建倒计时提醒配置。
适合:
- 到某个时间点后再进入倒计时
- 实现“稍后提醒我”
- 自定义提醒前后的倒计时流程
参数
countdown
倒计时参数。
schedule
触发日程。
attributes
展示属性,必填。
sound
提醒声音。
stopIntent
停止动作绑定的 AppIntent。
secondaryIntent
第二按钮动作绑定的 AppIntent。
示例
const countdown = AlarmManager.Countdown.create({
preAlert: 15 * 60,
postAlert: 5 * 60
})
const schedule = AlarmManager.Schedule.relative(21, 0)
const attributes = AlarmManager.Attributes.create({
alert: AlarmManager.AlertPresentation.create({
title: "准备休息",
stopButton: AlarmManager.Button.create({
title: "知道了",
textColor: "#ffffff",
systemImageName: "bed.double.fill"
}),
secondaryButton: AlarmManager.Button.create({
title: "15分钟后提醒",
textColor: "#ffffff",
systemImageName: "timer"
}),
secondaryBehavior: "countdown"
}),
countdown: AlarmManager.CountdownPresentation.create(
"休息倒计时中",
AlarmManager.Button.create({
title: "暂停",
textColor: "#ffffff",
systemImageName: "pause.fill"
})
),
paused: AlarmManager.PausedPresentation.create(
"已暂停",
AlarmManager.Button.create({
title: "恢复",
textColor: "#ffffff",
systemImageName: "play.fill"
})
),
tintColor: "#af52de",
metadata: {
scene: "night"
}
})
const configuration = AlarmManager.Configuration.countdown({
countdown,
schedule,
attributes,
sound: AlarmManager.Sound.default()
})
isAvailable
const isAvailable: boolean
表示当前环境是否支持 AlarmKit。
if (!AlarmManager.isAvailable) {
throw new Error("当前系统不支持 AlarmManager")
}
alarms
function alarms(): Promise<Alarm[]>
获取当前所有闹钟。
返回值
返回 Promise<Alarm[]>。
示例
const list = await AlarmManager.alarms()
for (const alarm of list) {
console.log(alarm.id, alarm.state)
}
schedule
function schedule(id: string, configuration: Configuration): Promise<Alarm>
根据配置创建并调度一个闹钟。
参数
id
闹钟唯一标识符。
必须使用 UUID.string() 生成。
configuration
通过 AlarmManager.Configuration.alarm()、timer() 或 countdown() 创建的配置对象。
返回值
返回创建后的 Alarm。
示例
const configuration = AlarmManager.Configuration.timer({
duration: 10 * 60,
attributes: AlarmManager.Attributes.create({
alert: AlarmManager.AlertPresentation.create({
title: "10分钟到了",
stopButton: AlarmManager.Button.create({
title: "结束",
textColor: "#ffffff",
systemImageName: "stop.fill"
})
}),
countdown: AlarmManager.CountdownPresentation.create(
"倒计时中",
AlarmManager.Button.create({
title: "暂停",
textColor: "#ffffff",
systemImageName: "pause.fill"
})
),
paused: AlarmManager.PausedPresentation.create(
"暂停中",
AlarmManager.Button.create({
title: "继续",
textColor: "#ffffff",
systemImageName: "play.fill"
})
),
tintColor: "#007aff"
}),
sound: AlarmManager.Sound.default()
})
const id = UUID.string()
const alarm = await AlarmManager.schedule(id, configuration)
console.log(alarm.id, alarm.state)
cancel
function cancel(id: string): Promise<boolean>
取消指定闹钟。
参数
id
要取消的闹钟 ID。
返回值
返回是否取消成功。
示例
const success = await AlarmManager.cancel(alarmId)
console.log("取消结果:", success)
stop
function stop(id: string): Promise<boolean>
停止指定闹钟或提醒。
通常用于提醒已经触发,或者需要主动终止当前流程时。
示例
const success = await AlarmManager.stop(alarmId)
console.log("停止结果:", success)
pause
function pause(id: string): Promise<boolean>
暂停指定倒计时或定时器。
示例
const success = await AlarmManager.pause(alarmId)
console.log("暂停结果:", success)
resume
function resume(id: string): Promise<boolean>
恢复已暂停的倒计时或定时器。
示例
const success = await AlarmManager.resume(alarmId)
console.log("恢复结果:", success)
startCountdown
function startCountdown(id: string): Promise<boolean>
启动指定闹钟的倒计时流程。
通常适用于通过 Configuration.countdown() 创建的配置,或提醒流程中存在“稍后提醒”语义的场景。
示例
const success = await AlarmManager.startCountdown(alarmId)
console.log("开始倒计时:", success)
addAlarmUpdateListener
function addAlarmUpdateListener(listener: AlarmUpdateListener): void
添加闹钟更新监听器。
当闹钟列表发生变化时,回调会收到最新的 Alarm[]。
示例
const listener = (alarms: AlarmManager.Alarm[]) => {
console.log("闹钟数量:", alarms.length)
for (const alarm of alarms) {
console.log(alarm.id, alarm.state)
}
}
AlarmManager.addAlarmUpdateListener(listener)
removeAlarmUpdateListener
function removeAlarmUpdateListener(listener?: AlarmUpdateListener): void
移除之前添加的监听器,不传移除所有。
参数
listener
要移除的监听器函数。
如果省略该参数,其具体行为以你的底层实现为准。
示例
const listener = (alarms: AlarmManager.Alarm[]) => {
console.log("更新:", alarms.length)
}
AlarmManager.addAlarmUpdateListener(listener)
AlarmManager.removeAlarmUpdateListener(listener)
在 AlarmManager 中使用 AppIntent
AlarmManager 支持通过 stopIntent 和 secondaryIntent 把按钮行为交给 AppIntent 处理。
这使得提醒按钮不仅可以停止或触发倒计时,还可以进一步执行脚本逻辑,例如:
- 停止提醒后写入本地状态
- 点击“完成”后更新任务状态
- 点击“稍后提醒”后刷新 Widget 或 Live Activity
- 结合其他全局 API 执行业务逻辑
AppIntent 的定义位置
所有 AppIntent 都必须定义在:
中。
不要把它们定义在 widget.tsx、live_activity.tsx、control_widget.tsx 或普通脚本文件中。
并且在执行时:
Script.env === "app_intents"
也就是说,perform 函数运行在 app_intents 环境。
AppIntent 相关类型
AppIntent
表示一个具体的意图实例。
AppIntentFactory
type AppIntentFactory<T> = (params: T) => AppIntent<T>
用于根据参数创建 AppIntent 实例。
type AppIntentPerform<T> = (params: T) => Promise<void>
表示被触发后执行的异步逻辑。
AppIntentProtocol
对于 AlarmManager,需要使用:
AppIntentProtocol.LiveActivityIntent
AppIntentManager.register
static register<T = undefined>(options: {
name: string
protocol: AppIntentProtocol
perform: AppIntentPerform<T>
}): AppIntentFactory<T>
用于注册一个新的 AppIntent。
参数
name
意图名称,必须唯一。
protocol
意图协议类型。
当意图被触发时执行的异步函数。
返回值
返回一个工厂函数,可通过传入参数创建对应的 AppIntent 实例。
AlarmManager 的 AppIntent 示例
下面示例展示如何在 app_intents.tsx 中定义两个可供 AlarmManager 使用的意图。
/// app_intents.tsx
export const StopFocusAlarmIntent = AppIntentManager.register({
name: "StopFocusAlarmIntent",
protocol: AppIntentProtocol.LiveActivityIntent,
perform: async ({ alarmId, taskId }: { alarmId: string; taskId: string }) => {
console.log("停止提醒:", alarmId, taskId)
// 这里可以执行你的业务逻辑
// 例如更新任务状态、记录日志、刷新界面等
await Storage.set(`task:${taskId}:finished`, true)
Widget.reloadAll()
}
})
export const SnoozeFocusAlarmIntent = AppIntentManager.register({
name: "SnoozeFocusAlarmIntent",
protocol: AppIntentProtocol.LiveActivityIntent,
perform: async ({ alarmId }: { alarmId: string }) => {
console.log("稍后提醒:", alarmId)
// 可按需刷新 UI 或做其他状态处理
Widget.reloadAll()
}
})
把 AppIntent 绑定到 AlarmManager
定义好 AppIntent 后,可以通过 stopIntent 和 secondaryIntent 传入配置中。
const alarmId = UUID.string()
const attributes = AlarmManager.Attributes.create({
alert: AlarmManager.AlertPresentation.create({
title: "专注时间结束",
stopButton: AlarmManager.Button.create({
title: "完成",
textColor: "#ffffff",
systemImageName: "checkmark"
}),
secondaryButton: AlarmManager.Button.create({
title: "稍后5分钟",
textColor: "#ffffff",
systemImageName: "timer"
}),
secondaryBehavior: "custom"
}),
countdown: AlarmManager.CountdownPresentation.create(
"倒计时中",
AlarmManager.Button.create({
title: "暂停",
textColor: "#ffffff",
systemImageName: "pause.fill"
})
),
paused: AlarmManager.PausedPresentation.create(
"已暂停",
AlarmManager.Button.create({
title: "继续",
textColor: "#ffffff",
systemImageName: "play.fill"
})
),
tintColor: "#007aff",
metadata: {
type: "focus"
}
})
const configuration = AlarmManager.Configuration.timer({
duration: 25 * 60,
attributes,
sound: AlarmManager.Sound.default(),
stopIntent: StopFocusAlarmIntent({
alarmId,
taskId: "task_001"
}),
secondaryIntent: SnoozeFocusAlarmIntent({
alarmId
})
})
await AlarmManager.schedule(alarmId, configuration)
上面这个例子里:
- 停止按钮会触发
StopFocusAlarmIntent
- 第二按钮会触发
SnoozeFocusAlarmIntent
- 第二按钮行为设为了
"custom",因此其实际逻辑由 secondaryIntent 决定
使用 countdown 行为的第二按钮
如果你希望第二按钮直接走 AlarmKit 的倒计时语义,可使用:
secondaryBehavior: "countdown"
示例:
const alarmId = UUID.string()
const attributes = AlarmManager.Attributes.create({
alert: AlarmManager.AlertPresentation.create({
title: "该休息了",
stopButton: AlarmManager.Button.create({
title: "关闭",
textColor: "#ffffff",
systemImageName: "xmark"
}),
secondaryButton: AlarmManager.Button.create({
title: "10分钟后提醒",
textColor: "#ffffff",
systemImageName: "timer"
}),
secondaryBehavior: "countdown"
}),
countdown: AlarmManager.CountdownPresentation.create(
"稍后提醒倒计时中",
AlarmManager.Button.create({
title: "暂停",
textColor: "#ffffff",
systemImageName: "pause.fill"
})
),
paused: AlarmManager.PausedPresentation.create(
"已暂停",
AlarmManager.Button.create({
title: "继续",
textColor: "#ffffff",
systemImageName: "play.fill"
})
),
tintColor: "#ff3b30"
})
const configuration = AlarmManager.Configuration.countdown({
countdown: AlarmManager.Countdown.create({
preAlert: 10 * 60
}),
attributes,
sound: AlarmManager.Sound.default()
})
await AlarmManager.schedule(alarmId, configuration)
这种方式更适合“稍后提醒”这种标准倒计时交互。
创建一次性闹钟
if (!AlarmManager.isAvailable) {
throw new Error("当前环境不支持 AlarmKit")
}
const alarmId = UUID.string()
const schedule = AlarmManager.Schedule.fixed(
new Date("2026-03-20T22:30:00")
)
const attributes = AlarmManager.Attributes.create({
alert: AlarmManager.AlertPresentation.create({
title: "该休息了",
stopButton: AlarmManager.Button.create({
title: "关闭",
textColor: "#ffffff",
systemImageName: "xmark"
}),
secondaryButton: AlarmManager.Button.create({
title: "10分钟后提醒",
textColor: "#ffffff",
systemImageName: "timer"
}),
secondaryBehavior: "countdown"
}),
countdown: AlarmManager.CountdownPresentation.create(
"稍后提醒倒计时中",
AlarmManager.Button.create({
title: "暂停",
textColor: "#ffffff",
systemImageName: "pause.fill"
})
),
paused: AlarmManager.PausedPresentation.create(
"已暂停",
AlarmManager.Button.create({
title: "继续",
textColor: "#ffffff",
systemImageName: "play.fill"
})
),
tintColor: "#ff3b30",
metadata: {
purpose: "sleep"
}
})
const configuration = AlarmManager.Configuration.alarm({
schedule,
attributes,
sound: AlarmManager.Sound.default()
})
const alarm = await AlarmManager.schedule(alarmId, configuration)
console.log("已创建:", alarm.id, alarm.state)
创建每周重复闹钟
const alarmId = UUID.string()
const schedule = AlarmManager.Schedule.weekly(7, 30, [2, 3, 4, 5, 6])
const attributes = AlarmManager.Attributes.create({
alert: AlarmManager.AlertPresentation.create({
title: "工作日早起提醒",
stopButton: AlarmManager.Button.create({
title: "起床",
textColor: "#ffffff",
systemImageName: "sun.max.fill"
})
}),
tintColor: "#34c759",
metadata: {
tag: "weekday-morning"
}
})
const configuration = AlarmManager.Configuration.alarm({
schedule,
attributes,
sound: AlarmManager.Sound.default()
})
await AlarmManager.schedule(alarmId, configuration)
创建番茄钟定时器
const alarmId = UUID.string()
const attributes = AlarmManager.Attributes.create({
alert: AlarmManager.AlertPresentation.create({
title: "当前专注时段已结束",
stopButton: AlarmManager.Button.create({
title: "完成",
textColor: "#ffffff",
systemImageName: "checkmark.circle.fill"
})
}),
countdown: AlarmManager.CountdownPresentation.create(
"专注中",
AlarmManager.Button.create({
title: "暂停",
textColor: "#ffffff",
systemImageName: "pause.fill"
})
),
paused: AlarmManager.PausedPresentation.create(
"专注已暂停",
AlarmManager.Button.create({
title: "继续",
textColor: "#ffffff",
systemImageName: "play.fill"
})
),
tintColor: "#ff9500",
metadata: {
type: "pomodoro",
duration: "1500"
}
})
const configuration = AlarmManager.Configuration.timer({
duration: 25 * 60,
attributes,
sound: AlarmManager.Sound.default()
})
await AlarmManager.schedule(alarmId, configuration)
创建可手动启动的倒计时提醒
const alarmId = UUID.string()
const countdown = AlarmManager.Countdown.create({
preAlert: 5 * 60,
postAlert: 60
})
const attributes = AlarmManager.Attributes.create({
alert: AlarmManager.AlertPresentation.create({
title: "稍后提醒时间到了",
stopButton: AlarmManager.Button.create({
title: "知道了",
textColor: "#ffffff",
systemImageName: "bell.slash.fill"
})
}),
countdown: AlarmManager.CountdownPresentation.create(
"稍后提醒中",
AlarmManager.Button.create({
title: "暂停",
textColor: "#ffffff",
systemImageName: "pause.fill"
})
),
paused: AlarmManager.PausedPresentation.create(
"倒计时已暂停",
AlarmManager.Button.create({
title: "继续",
textColor: "#ffffff",
systemImageName: "play.fill"
})
),
tintColor: "#af52de"
})
const configuration = AlarmManager.Configuration.countdown({
countdown,
attributes,
sound: AlarmManager.Sound.default()
})
await AlarmManager.schedule(alarmId, configuration)
await AlarmManager.startCountdown(alarmId)
查询与控制闹钟
const alarms = await AlarmManager.alarms()
console.log("当前闹钟数量:", alarms.length)
const firstAlarm = alarms[0]
if (firstAlarm) {
await AlarmManager.pause(firstAlarm.id)
await AlarmManager.resume(firstAlarm.id)
await AlarmManager.stop(firstAlarm.id)
}
监听闹钟状态变化
const listener = (alarms: AlarmManager.Alarm[]) => {
const summary = alarms.map(item => ({
id: item.id,
state: item.state
}))
console.log("最新闹钟状态:", JSON.stringify(summary, null, 2))
}
AlarmManager.addAlarmUpdateListener(listener)
// 不再需要时移除
// AlarmManager.removeAlarmUpdateListener(listener)
执行环境说明
AlarmManager 本身是全局 API,可以在普通脚本中直接使用。
但如果你给 AlarmManager 绑定了 AppIntent,那么这些意图的 perform 函数执行环境为:
Script.env === "app_intents"
这意味着:
AlarmManager.schedule() 等闹钟创建逻辑,通常运行在普通脚本环境
stopIntent / secondaryIntent 对应的逻辑,运行在 app_intents.tsx 中定义的 perform 里
- 你可以在
perform 中执行网络请求、状态更新、Widget 刷新、Live Activity 刷新等逻辑
最佳实践
始终使用 UUID.string() 生成 alarmId
这是 AlarmManager 的硬性要求。不要自己构造 ID。
const alarmId = UUID.string()
保留创建时的 alarmId
创建成功后,应自行保存该 alarmId,方便后续暂停、恢复、停止、取消。
比如任务 ID、场景、来源等。
metadata: {
taskId: "task_123",
scene: "study",
source: "focus-page"
}
把 AppIntent 集中定义在 app_intents.tsx
不要散落在不同文件中,方便维护。
为 AppIntent 定义明确的参数类型
这样能获得更好的类型检查和自动补全。
perform: async ({ alarmId, taskId }: { alarmId: string; taskId: string }) => {
// ...
}
需要标准“稍后提醒”时优先使用 countdown
如果只是实现标准的“几分钟后再提醒”,推荐使用:
secondaryBehavior: "countdown"
如果需要完全自定义逻辑,再使用:
secondaryBehavior: "custom"
secondaryIntent: ...
注意事项
Attributes.create(...) 可能返回 null
const attributes = AlarmManager.Attributes.create(...)
返回类型是 Attributes | null,建议在严格场景下进行判空。
Configuration 创建方法也可能返回 null
const configuration = AlarmManager.Configuration.timer(...)
返回类型同样允许为 null,建议在调用 schedule() 前先校验。
pause、resume、startCountdown 不适用于所有闹钟类型
这些方法更适合定时器或倒计时场景。对于普通固定时间闹钟,某些操作可能没有实际意义。
完整示例
下面给出一个包含 AppIntent 的完整示例。
/// app_intents.tsx
export const StopPomodoroIntent = AppIntentManager.register({
name: "StopPomodoroIntent",
protocol: AppIntentProtocol.LiveActivityIntent,
perform: async ({ alarmId, sessionId }: { alarmId: string; sessionId: string }) => {
console.log("番茄钟结束:", alarmId, sessionId)
await Storage.set(`pomodoro:${sessionId}:done`, true)
Widget.reloadAll()
}
})
export const ExtendPomodoroIntent = AppIntentManager.register({
name: "ExtendPomodoroIntent",
protocol: AppIntentProtocol.LiveActivityIntent,
perform: async ({ alarmId, extraMinutes }: { alarmId: string; extraMinutes: number }) => {
console.log("延长番茄钟:", alarmId, extraMinutes)
Widget.reloadAll()
}
})
/// 普通脚本文件
async function main() {
if (!AlarmManager.isAvailable) {
console.log("当前系统不支持 AlarmManager")
return
}
const listener = (alarms: AlarmManager.Alarm[]) => {
console.log(
"闹钟更新:",
alarms.map(item => `${item.id}:${item.state}`).join(", ")
)
}
AlarmManager.addAlarmUpdateListener(listener)
const alarmId = UUID.string()
const attributes = AlarmManager.Attributes.create({
alert: AlarmManager.AlertPresentation.create({
title: "专注时间结束",
stopButton: AlarmManager.Button.create({
title: "完成",
textColor: "#ffffff",
systemImageName: "checkmark"
}),
secondaryButton: AlarmManager.Button.create({
title: "延长5分钟",
textColor: "#ffffff",
systemImageName: "timer"
}),
secondaryBehavior: "custom"
}),
countdown: AlarmManager.CountdownPresentation.create(
"专注中",
AlarmManager.Button.create({
title: "暂停",
textColor: "#ffffff",
systemImageName: "pause.fill"
})
),
paused: AlarmManager.PausedPresentation.create(
"已暂停",
AlarmManager.Button.create({
title: "继续",
textColor: "#ffffff",
systemImageName: "play.fill"
})
),
tintColor: "#007aff",
metadata: {
feature: "focus-mode"
}
})
if (!attributes) {
throw new Error("创建 Attributes 失败")
}
const configuration = AlarmManager.Configuration.timer({
duration: 15 * 60,
attributes,
sound: AlarmManager.Sound.default(),
stopIntent: StopPomodoroIntent({
alarmId,
sessionId: "session_001"
}),
secondaryIntent: ExtendPomodoroIntent({
alarmId,
extraMinutes: 5
})
})
if (!configuration) {
throw new Error("创建 Configuration 失败")
}
const alarm = await AlarmManager.schedule(alarmId, configuration)
console.log("已创建闹钟:", alarm.id, alarm.state)
const current = await AlarmManager.alarms()
console.log("当前闹钟:", current.map(item => item.id))
await AlarmManager.pause(alarmId)
await AlarmManager.resume(alarmId)
// 结束后可移除监听
// AlarmManager.removeAlarmUpdateListener(listener)
}
main().catch(error => {
console.log(String(error))
})