View in English

  • 打开菜单 关闭菜单
  • Apple Developer
搜索
关闭搜索
  • Apple Developer
  • 新闻
  • 探索
  • 设计
  • 开发
  • 分发
  • 支持
  • 账户
在“”范围内搜索。

快捷链接

5 快捷链接

视频

打开菜单 关闭菜单
  • 专题
  • 相关主题
  • 所有视频
  • 关于

更多视频

大多数浏览器和
Developer App 均支持流媒体播放。

  • 简介
  • 转写文稿
  • 代码
  • 使用 AlarmKit API 实现唤醒功能

    铃-铃-铃!从你食谱 App 中的倒计时器到你旅行规划 App 中的闹钟,iOS 和 iPadOS 26 中的 AlarmKit 框架可将计时器和闹钟引入到锁定屏幕、灵动岛等其他地方。了解如何使用 App Intents 框架来创建和管理你 App 的闹钟,自定闹钟的实时活动,并提供自定提醒操作。为了充分从这个视频中获益,建议你先观看 WWDC23 讲座“了解 ActivityKit”。

    章节

    • 0:00 - 开场介绍
    • 0:32 - 概览
    • 1:39 - 授权
    • 3:06 - 创建
    • 16:32 - 生命周期

    资源

    • ActivityKit
    • AlarmKit
    • App Intents
    • Creating your first app intent
    • Human Interface Guidelines: Live Activities
    • Scheduling an alarm with AlarmKit
      • 高清视频
      • 标清视频

    相关视频

    WWDC25

    • 了解 App Intents

    WWDC23

    • 了解 ActivityKit
  • 搜索此视频…

    Hey, I’m Anton, an engineer on the system experience team. In this session, you’ll meet AlarmKit, a framework that allows you to create alarms in your app. In this video, I will first walk you through the experience you can build with AlarmKit then I’ll discuss how you can get your app authorization for using this framework, how to create an alarm, and how you can manage its lifecycle. I’ll start with the experience. An alarm is a prominent alert for things that occur at a fixed, pre-determined time. It’s based on a schedule or a countdown. When it fires, the alert breaks through the silent mode and the current focus.

    In the alert, people are presented with the custom alarm title, as well as the name of your app People have the option of stopping the alert or snoozing it with an optional snooze button.

    Alternatively, an alarm can have a custom button whose action is defined by an app intent.

    Alarms are also supported in other system experiences, such as in StandBy and right on Apple Watch, if it’s paired to iPhone when the alarm fires.

    Alarms support a custom countdown interface using Live Activities that your app provides. This can be viewed on the Lock Screen as well as in the dynamic island and in StandBy.

    People opt in to enable alarm functionality for each app on their device.

    Now that you know what an alarm is, let’s talk about what you need to do to allow people to authorize your app to schedule alarms.

    Before your app can schedule alarms, people will need to consent by providing authorization.

    You can request authorization manually, or it will be requested automatically when you create your first alarm. At any time, people can change their authorization status in the Settings app.

    Setting up authorization is simple, you just need to add NSAlarmKitUsageDescription to your app’s info plist explaining the use case for presenting alarms.

    Provide a short and descriptive explanation of how your app will be using alarms, to help people make the best decision. To request authorization manually, you can use the AlarmManager requestAuthorization API If a choice has not previously been made, a prompt will be shown containing the usage description.

    You can check authorization status before scheduling an alarm by querying the authorizationState in the AlarmManager class.

    In this case, if it’s not determined, I can request authorization manually. If authorized, I can proceed with scheduling the alarm. If denied, it’s important to make it clear in your app’s interface that the alarm will not be scheduled. Now that you are familiar with authorization setup for alarms, let’s talk about how to create an alarm. The main parts required for creating an alarm are countdown duration, A schedule with a specific date or recurrence pattern Appearance configuration, handling of custom actions And associated sound.

    Let’s start with countdown duration. An alarm can have a pre-alert and post-alert countdown interval. When an alarm is first scheduled it will display the countdown UI which will appear for the pre-alert countdown duration.

    When the pre-alert duration elapses, the alarm fires and displays the alert UI, customized with your configuration.

    If the alarm is snoozed the countdown UI will appear again for the duration of the post-alert interval.

    Once this interval elapses, the alarm will fire again and can be snoozed or dismissed.

    In this example, I'm setting up a timer with a pre alert duration of 10 minutes. Once it fires and is repeated it will count down the 5 minute post alert duration and fire again. When creating an alarm you can also provide a schedule, which can be either fixed or relative.

    A fixed schedule specifies a single future date at which the alarm will alert. This schedule is absolute and does not change when device timezone changes. In this example, I set up an alarm to go off for the WWDC Keynote. I create the date components for June 9th at 9:41 am. I then use those components to create the date.

    Next, I pass the date to my alarm schedule using its fixed initializer.

    I can also specify a relative schedule for my alarm. This includes the time of day and optional weekly recurrence pattern. Relative schedule accounts for timezone changes.

    In this example, I’m setting the alarm to go off at 7 am every Monday, Wednesday, and Friday. I set the hour and the minute for the time portion and specify the daily occurrence.

    Now that you’re familiar with how to schedule an alarm, let’s move onto customizing alarm appearance. There are a number of elements you can customize.

    I want to create a cooking timer in my app, and I want to customize how the alert appears when it goes off. I start off by creating the alert button, which is done using the AlarmButton struct. It allows me to specify the text, textColor, and the systemImage of the button.

    I use it to define the stop button, which will be titled “Dismiss”, and have a white text color.

    It will also include an SF Symbol, which will be used when the alert is shown in the dynamic island.

    I can now create the alert presentation and set the alarm title, stating that food is done. I also include the stop button I just created.

    Next, I will create the alarm attributes. Think of this as the information required to render the presentations of your alarm. I will pass the alert presentation I just created in the presentation parameter.

    Lastly, I will create alarm configuration. Think of this as all the pieces required to schedule an alarm, including a countdown duration, a schedule, and the attributes.

    I will pass the attributes to the alarm configuration.

    I have now set up my alarm alert presentation with a dismiss button.

    If your alarm just needs to show an alert, this is all you need to do to set up its appearance.

    But if you would like your alarm to show a countdown interface, there are a few more steps you need to take. I’ll go through those for my cooking alarm next.

    I will first add a repeat button to my alert to trigger a countdown.

    I create the repeat button using the AlarmButton struct and set its title to repeat. I will also specify a white text color, and a repeat icon, which will appear when the alarm alerts in the Dynami Island.

    When I create the alert presentation I now also include my repeat button.

    The secondaryButton behavior parameter, specifies whether the secondary button transitions the alarm to the countdown state, like repeating a timer or snoozing an alarm, or whether it executes a custom action. When my repeat button is tapped, I want the alert to transition to a countdown in this case. I specify this by setting secondaryButtonBehavior to countdown.

    Just like before, I will create the alarm attributes with the alert presentation, and then the AlarmConfiguration including those attributes.

    I have now added a repeat button to my alert that will start a countdown. Next, I need to implement a Live Activity to show the UI for my countdown. If your alarm supports countdown functionality, your app is required to implement it using a Live Activity. I will do that next. I will create a countdown to inform me when the food is done cooking. It will appear on the Lock Screen, in the Dynamic Island, and in StandBy.

    If you know how to build a Live Activity, you already know how to create a custom interface for your countdown. You will need to add your countdown Live Activity to your app’s widget extension.

    If you don’t have one, do not get alarmed! You can get started by watching the WWDC23 video called “Meet ActivityKit”. You will then set up an ActivityConfiguration, and specify AlarmAttributes with your metadata type.

    In this case, I can set up an ActivityConfiguration and specify that it will use alarm attributes and my CookingData metadata. I will first focus on the Lock Screen.

    My alarm countdown can be in a countdown or paused state. I’ll provide a corresponding view for each of these states.

    To do that, I check the current mode of the alarm in the context object and render the appropriate view.

    I first handle the countdown state and provide my countdown view.

    Next, I handle the paused state and provide my paused view.

    I will now set up the expanded regions of the Dynamic Island appearance. They contain my alarm title, countdown, and buttons. I then set up the compact and minimal Dynamic Island views. These will contain my alarm countdown and an icon. Now that I’ve set up my basic Live Activity countdown, I’d like to add an icon to indicate how the food is being cooked. I can provide this additional information in my alarm metadata.

    My CookingData is a struct that conforms to the AlarmMetadata protocol. I define a string enum to specify the method of cooking and include frying and grilling as options. I then create a property to store my method of cooking.

    I am now ready to use my cooking data metadata. When scheduling the alarm in my app, I create the cooking data object and specify frying as the method of cooking.

    I then include this custom metadata when creating the alarm attributes.

    In my Live Activity, I will access the method of cooking in my custom metadata using the context attributes.

    I can then use the method of cooking to create an icon. Now, when my countdown is rendered, it has the frying icon I generated using the method of cooking in my cooking metadata. I use it both on the Lock Screen and in the Dynamic Island.

    I have now successfully set up my alarm countdown using a Live Activity. I also created a custom icon for my alarm countdown using alarm metadata.

    If your alarm supports countdown functionality, the system will guarantee that a countdown interface will be shown. In some cases, your Live Activity cannot be shown, for example, after device restarts and before it’s first unlocked. In that case, you can still customize the system's presentation of your countdown.

    I will now set up the system presentation for my cooking alarm countdown. I will start by defining the paused button using the AlarmButton struct. And set it to have a pause system icon.

    Next, I’ll create the countdown presentation and set the title to say that the food is cooking, and include my pause button.

    Now that I have defined the countdown presentation, I will include it as part of my alarm attributes. Because my alarm supports pause functionality, I will also set up the paused system presentation for my cooking countdown.

    When my countdown is paused, I want people to be able to resume it. I start by defining a resume button using the AlarmButton struct. And setting it to have a play icon.

    I then create the paused presentation and set the title to cooking being paused.

    I also pass in my resume button.

    I can now add my paused presentation to my alarm attributes.

    I have now handled the alert, countdown, and paused system presentations. Let’s take a moment to talk about the tint color. It is used throughout these presentations and helps people associate your alarm to your app. I pass it as part of my alarm attributes. In the alert presentation, it is used to set the fill color of the secondary button.

    On the lock screen, it is used to tint the symbol in the secondary button as well as the alarm title and the countdown.

    Similarly, it is used in the Dynamic Island. Now that you are familiar with setting up the alarm appearance, let’s move onto customizing its actions. AlarmKit gives you the ability to run your own code when someone taps an alarm button. You can do this using an app intent. You can provide a custom app intent for the stop button or for the secondary button.

    Let’s create a custom secondary button that will execute an app intent to open my app when tapped. To accomplish that, I will need to modify the alert appearance. I start off by creating an open button using the AlarmButton struct. It will be titled “Open”, have a white text color and an arrow icon in the Dynamic Island.

    When I create the alert presentation, I will include the open button as the secondary button.

    Because I want this button to execute a custom action, I will change the secondary button behavior to custom.

    My custom secondary button is now ready.

    Let’s set up an action using an app intent to open my app when the button is tapped.

    This is the open app intent I’d like to use. It includes the alarm identifier for which the button was tapped. It also sets the openAppWhenRun flag to true to indicate that I want my app to be opened when the intent is executed.

    Once my app is opened, I can do additional tasks like show a more detailed view for the alarm with that identifier.

    Let’s use the intent I just created.

    When scheduling the alarm, I create a unique identifier that allows me to track that alarm after creation.

    I create an instance of the OpenInApp intent, and pass in the unique identifier of the alarm.

    When I create my alarm configuration, I now include the secondary intent to indicate to the system that this is the intent I would like it to run when secondary button is tapped.

    I have now added a custom open button to my alert, defined an app intent to open my app, and indicated to the system to run that intent when the open button is tapped. Let’s now take a moment to talk about how to configure the sound of your alarm. If you don’t specify a sound parameter, your alarm will use a default system sound. You can also provide a custom sound for your alarm.

    Because AlarmKit uses ActivityKit for alarm presentation, you can define a custom sound by using its AlertSound struct.

    You will need to specify the name of the sound file, which should be either in your app’s main bundle or Library/Sounds folder of your app’s data container. Once you have finished setting up your alarm, you are now ready to manage it in the system. You can do so using the AlarmManager class. After I’ve configured my alarm, I can schedule it with the system. I can do so by using the alarm's unique identifier and the configuration I created earlier. This identifier should be used to track the alarm through its lifecycle.

    You have full control over the lifecycle of the alarm. You can transition it to a countdown state, as well as cancel, stop, pause, or resume it.

    I'd like to leave you with a few best practices when using AlarmKit. Alarms are a great fit for countdowns with a specific interval, like a cooking timer, or recurring alerts with a schedule, like a wake-up alarm. They are not a replacement for other prominent notifications, like critical alerts or time-sensitive notifications.

    Aim for clarity with your alert presentation. Alerts are prominently displayed, and you'll want to make it easy for someone to understand what the alarm is, and what actions they can take.

    If your alarm supports a countdown, consider including the key elements of the countdown in your Live Activity. This includes the remaining duration, a dismiss button, and a pause or resume button. Today, you learned how to use AlarmKit to create alarms and manage their lifecycle in the system. You are now ready to try it in your app. Use AlarmKit to configure alarms for your app’s use cases. Create custom countdown experiences on the Lock Screen and in the Dynamic Island with Live Activities. Add custom actions to your alarms using App Intents.

    That’s all there is time for. Thanks for joining!

    • 2:41 - Check authorization status

      // Check authorization status
      
      import AlarmKit
      
      func checkAuthorization() {
      
        switch AlarmManager.shared.authorizationState {
          case .notDetermined:
            // Manually request authorization
          case .authorized:
            // Proceed with scheduling
          case .denied:
            // Inform status is not authorized
        }
        
      }
    • 4:08 - Set up the countdown duration

      // Set up the countdown duration
      
      import AlarmKit
      
      func scheduleAlarm() {
      
        /* ... */
      
        let countdownDuration = Alarm.CountdownDuration(preAlert: (10 * 60), postAlert: (5 * 60))
      
        /* ... */
      }
    • 4:40 - Set a fixed schedule

      // Set a fixed schedule
      
      import AlarmKit
      
      func scheduleAlarm() {
      
        /* ... */
      
        let keynoteDateComponents = DateComponents(
          calendar: .current,
          year: 2025,
          month: 6,
          day: 9,
          hour: 9,
          minute: 41)
        let keynoteDate = Calendar.current.date(from: keynoteDateComponents)!
        let scheduleFixed = Alarm.Schedule.fixed(keynoteDate)
      
        /* ... */
      
      }
    • 5:13 - Set a relative schedule

      // Set a relative schedule
      
      import AlarmKit
      
      func scheduleAlarm() {
      
        /* ... */
      
        let time = Alarm.Schedule.Relative.Time(hour: 7, minute: 0)
        let recurrence = Alarm.Schedule.Relative.Recurrence.weekly([
          .monday,
          .wednesday,
          .friday
        ])
        
        let schedule = Alarm.Schedule.Relative(time: time, repeats: recurrence)
      
        /* ... */
      
      }
    • 5:43 - Set up alert appearance with dismiss button

      // Set up alert appearance with dismiss button
      
      import AlarmKit
      
      func scheduleAlarm() async throws {
          typealias AlarmConfiguration = AlarmManager.AlarmConfiguration<CookingData>
          
          let id = UUID()
          let duration = Alarm.CountdownDuration(preAlert: (10 * 60), postAlert: (5 * 60))
          
          let stopButton = AlarmButton(
              text: "Dismiss",
              textColor: .white,
              systemImageName: "stop.circle")
          
          let alertPresentation = AlarmPresentation.Alert(
              title: "Food Ready!",
              stopButton: stopButton)
          
          let attributes = AlarmAttributes<CookingData>(
              presentation: AlarmPresentation(
                  alert: alertPresentation),
              tintColor: Color.green)
          
          let alarmConfiguration = AlarmConfiguration(
              countdownDuration: duration,
              attributes: attributes)
          
          try await AlarmManager.shared.schedule(id: id, configuration: alarmConfiguration)
      }
    • 7:17 - Set up alert appearance with repeat button

      // Set up alert appearance with repeat button
      
      import AlarmKit
      
      func scheduleAlarm() async throws {
          typealias AlarmConfiguration = AlarmManager.AlarmConfiguration<CookingData>
          
          let id = UUID()
          let duration = Alarm.CountdownDuration(preAlert: (10 * 60), postAlert: (5 * 60))
          
          let stopButton = AlarmButton(
              text: "Dismiss",
              textColor: .white,
              systemImageName: "stop.circle")
          
          let repeatButton = AlarmButton(
              text: "Repeat",
              textColor: .white,
              systemImageName: "repeat.circle")
          
          let alertPresentation = AlarmPresentation.Alert(
              title: "Food Ready!",
              stopButton: stopButton,
              secondaryButton: repeatButton,
              secondaryButtonBehavior: .countdown)
          
          let attributes = AlarmAttributes<CookingData>(
              presentation: AlarmPresentation(alert: alertPresentation),
              tintColor: Color.green)
          
          let alarmConfiguration = AlarmConfiguration(
              countdownDuration: duration,
              attributes: attributes)
          
          try await AlarmManager.shared.schedule(id: id, configuration: alarmConfiguration)
      }
    • 9:15 - Create a Live Activity for a countdown

      // Create a Live Activity for a countdown
      
      import AlarmKit
      import ActivityKit
      import WidgetKit
      
      struct AlarmLiveActivity: Widget {
      
        var body: some WidgetConfiguration {
          ActivityConfiguration(for: AlarmAttributes<CookingData>.self) { context in
      
            switch context.state.mode {
            case .countdown:
              countdownView(context)
            case .paused:
              pausedView(context)
            case .alert:
              alertView(context)
            }
      
          } dynamicIsland: { context in 
      
            DynamicIsland {
              DynamicIslandExpandedRegion(.leading) {
                leadingView(context)
              }
              DynamicIslandExpandedRegion(.trailing) {
                trailingView(context)
              }
            } compactLeading: {
              compactLeadingView(context)
            } compactTrailing: {
              compactTrailingView(context)
            } minimal: {
              minimalView(context)
            }
      
          }
        }
      }
    • 10:26 - Create custom metadata for the Live Activity

      // Create custom metadata for the Live Activity
      
      import AlarmKit
      
      struct CookingData: AlarmMetadata {
        let method: Method
          
        init(method: Method) {
          self.method = method
        }
          
        enum Method: String, Codable {
          case frying = "frying.pan"
          case grilling = "flame"
        }
      }
    • 10:43 - Provide custom metadata to the Live Activity

      // Provide custom metadata to the Live Activity
      
      import AlarmKit
      
      func scheduleAlarm() async throws {
          typealias AlarmConfiguration = AlarmManager.AlarmConfiguration<CookingData>
          
          let id = UUID()
          let duration = Alarm.CountdownDuration(preAlert: (10 * 60), postAlert: (5 * 60))
          let customMetadata = CookingData(method: .frying)
          
          let stopButton = AlarmButton(
              text: "Dismiss",
              textColor: .white,
              systemImageName: "stop.circle")
          
          let repeatButton = AlarmButton(
              text: "Repeat",
              textColor: .white,
              systemImageName: "repeat.circle")
          
          let alertPresentation = AlarmPresentation.Alert(
              title: "Food Ready!",
              stopButton: stopButton,
              secondaryButton: repeatButton,
              secondaryButtonBehavior: .countdown)
          
          let attributes = AlarmAttributes<CookingData>(
              presentation: AlarmPresentation(alert: alertPresentation),
              metadata: customMetadata,
              tintColor: Color.green)
          
          let alarmConfiguration = AlarmConfiguration(
              countdownDuration: duration,
              attributes: attributes)
          
          try await AlarmManager.shared.schedule(id: id, configuration: alarmConfiguration)
      }
    • 11:01 - Use custom metadata in the Live Activity

      // Use custom metadata in the Live Activity
      
      import AlarmKit
      import ActivityKit
      import WidgetKit
      
      struct AlarmLiveActivity: Widget {
      
        var body: some WidgetConfiguration { /* ... */ }
      
        func alarmIcon(context: ActivityViewContext<AlarmAttributes<CookingData>>) -> some View {
          let method = context.attributes.metadata?.method ?? .grilling
          return Image(systemName: method.rawValue)
        }
      
      }
    • 12:03 - Set up the system countdown appearance

      // Set up the system countdown appearance
      
      import AlarmKit
      
      func scheduleAlarm() async throws {
        typealias AlarmConfiguration = AlarmManager.AlarmConfiguration<CookingData>
          
        let id = UUID()
        let duration = Alarm.CountdownDuration(preAlert: (10 * 60), postAlert: (5 * 60))
        let customMetadata = CookingData(method: .frying)
      
        let stopButton = AlarmButton(
          text: "Dismiss",
          textColor: .white,
          systemImageName: "stop.circle")
      
        let repeatButton = AlarmButton(
          text: "Repeat",
          textColor: .white,
          systemImageName: "repeat.circle")
      
        let alertPresentation = AlarmPresentation.Alert(
          title: "Food Ready!",
          stopButton: stopButton,
          secondaryButton: repeatButton,
          secondaryButtonBehavior: .countdown)
      
        let pauseButton = AlarmButton(
          text: "Pause",
          textColor: .green,
          systemImageName: "pause")
      
        let countdownPresentation = AlarmPresentation.Countdown(
          title: "Cooking",
          pauseButton: pauseButton)
      
        let attributes = AlarmAttributes<CookingData>(
          presentation: AlarmPresentation(
            alert: alertPresentation,
            countdown: countdownPresentation),
          metadata: customMetadata,
          tintColor: Color.green)
      
        let alarmConfiguration = AlarmConfiguration(
          countdownDuration: duration,
          attributes: attributes)
      
        try await AlarmManager.shared.schedule(id: id, configuration: alarmConfiguration)
        
      }
    • 12:43 - Set up the system paused appearance

      // Set up the system paused appearance
      
      import AlarmKit
      
      func scheduleAlarm() async throws {
        typealias AlarmConfiguration = AlarmManager.AlarmConfiguration<CookingData>
          
        let id = UUID()
        let duration = Alarm.CountdownDuration(preAlert: (10 * 60), postAlert: (5 * 60))
        let customMetadata = CookingData(method: .frying)
      
        let stopButton = AlarmButton(
          text: "Dismiss",
          textColor: .white,
          systemImageName: "stop.circle")
      
        let repeatButton = AlarmButton(
          text: "Repeat",
          textColor: .white,
          systemImageName: "repeat.circle")
      
        let alertPresentation = AlarmPresentation.Alert(
          title: "Food Ready!",
          stopButton: stopButton,
          secondaryButton: repeatButton,
          secondaryButtonBehavior: .countdown)
      
        let pauseButton = AlarmButton(
          text: "Pause",
          textColor: .green,
          systemImageName: "pause")
      
        let countdownPresentation = AlarmPresentation.Countdown(
          title: "Cooking",
          pauseButton: pauseButton)
      
        let resumeButton = AlarmButton(
          text: "Resume",
          textColor: .green,
          systemImageName: "play")
      
        let pausedPresentation = AlarmPresentation.Paused(
          title: "Paused",
          resumeButton: resumeButton)
      
        let attributes = AlarmAttributes<CookingData>(
          presentation: AlarmPresentation(
            alert: alertPresentation,
            countdown: countdownPresentation,
            paused: pausedPresentation),
          metadata: customMetadata,
          tintColor: Color.green)
      
        let alarmConfiguration = AlarmConfiguration(
          countdownDuration: duration,
          attributes: attributes)
      
        try await AlarmManager.shared.schedule(id: id, configuration: alarmConfiguration)
        
      }
    • 14:09 - Add a custom button

      // Add a custom button
      
      import AlarmKit
      import AppIntents
      
      func scheduleAlarm() async throws {
        typealias AlarmConfiguration = AlarmManager.AlarmConfiguration<CookingData>
          
        let id = UUID()
        let duration = Alarm.CountdownDuration(preAlert: (10 * 60), postAlert: (5 * 60))
        let customMetadata = CookingData(method: .frying)
        let secondaryIntent = OpenInApp(alarmID: id.uuidString)
      
        let stopButton = AlarmButton(
          text: "Dismiss",
          textColor: .white,
          systemImageName: "stop.circle")
      
        let openButton = AlarmButton(
          text: "Open",
          textColor: .white,
          systemImageName: "arrow.right.circle.fill")
      
        let alertPresentation = AlarmPresentation.Alert(
          title: "Food Ready!",
          stopButton: stopButton,
          secondaryButton: openButton,
          secondaryButtonBehavior: .custom)
      
        let pauseButton = AlarmButton(
          text: "Pause",
          textColor: .green,
          systemImageName: "pause")
      
        let countdownPresentation = AlarmPresentation.Countdown(
          title: "Cooking",
          pauseButton: pauseButton)
      
        let resumeButton = AlarmButton(
          text: "Resume",
          textColor: .green,
          systemImageName: "play")
      
        let pausedPresentation = AlarmPresentation.Paused(
          title: "Paused",
          resumeButton: resumeButton)
      
        let attributes = AlarmAttributes<CookingData>(
          presentation: AlarmPresentation(
            alert: alertPresentation,
            countdown: countdownPresentation,
            paused: pausedPresentation),
          metadata: customMetadata,
          tintColor: Color.green)
      
        let alarmConfiguration = AlarmConfiguration(
          countdownDuration: duration,
          attributes: attributes,
          secondaryIntent: secondaryIntent)
      
        try await AlarmManager.shared.schedule(id: id, configuration: alarmConfiguration)
        
      }
      
      public struct OpenInApp: LiveActivityIntent {
          public func perform() async throws -> some IntentResult { .result() }
          
          public static var title: LocalizedStringResource = "Open App"
          public static var description = IntentDescription("Opens the Sample app")
          public static var openAppWhenRun = true
          
          @Parameter(title: "alarmID")
          public var alarmID: String
          
          public init(alarmID: String) {
              self.alarmID = alarmID
          }
          
          public init() {
              self.alarmID = ""
          }
      }
    • 16:10 - Add a custom sound

      // Add a custom sound
      
      import AlarmKit
      import AppIntents
      
      func scheduleAlarm() async throws {
        typealias AlarmConfiguration = AlarmManager.AlarmConfiguration<CookingData>
        
        let id = UUID()
        let duration = Alarm.CountdownDuration(preAlert: (10 * 60), postAlert: (5 * 60))
        let customMetadata = CookingData(method: .frying)
        let secondaryIntent = OpenInApp(alarmID: id.uuidString)
      
        let stopButton = AlarmButton(
          text: "Dismiss",
          textColor: .white,
          systemImageName: "stop.circle")
      
        let openButton = AlarmButton(
          text: "Open",
          textColor: .white,
          systemImageName: "arrow.right.circle.fill")
      
        let alertPresentation = AlarmPresentation.Alert(
          title: "Food Ready!",
          stopButton: stopButton,
          secondaryButton: openButton,
          secondaryButtonBehavior: .custom)
      
        let pauseButton = AlarmButton(
          text: "Pause",
          textColor: .green,
          systemImageName: "pause")
      
        let countdownPresentation = AlarmPresentation.Countdown(
          title: "Cooking",
          pauseButton: pauseButton)
      
        let resumeButton = AlarmButton(
          text: "Resume",
          textColor: .green,
          systemImageName: "play")
      
        let pausedPresentation = AlarmPresentation.Paused(
          title: "Paused",
          resumeButton: resumeButton)
      
        let attributes = AlarmAttributes<CookingData>(
          presentation: AlarmPresentation(
            alert: alertPresentation,
            countdown: countdownPresentation,
            paused: pausedPresentation),
          metadata: customMetadata,
          tintColor: Color.green)
      
        let sound = AlertConfiguration.AlertSound.named("Chime")
      
        let alarmConfiguration = AlarmConfiguration(
          countdownDuration: duration,
          attributes: attributes,
          secondaryIntent: secondaryIntent,
          sound: sound)
      
        try await AlarmManager.shared.schedule(id: id, configuration: alarmConfiguration)
        
      }
      
      public struct OpenInApp: LiveActivityIntent {
          public func perform() async throws -> some IntentResult { .result() }
          
          public static var title: LocalizedStringResource = "Open App"
          public static var description = IntentDescription("Opens the Sample app")
          public static var openAppWhenRun = true
          
          @Parameter(title: "alarmID")
          public var alarmID: String
          
          public init(alarmID: String) {
              self.alarmID = alarmID
          }
          
          public init() {
              self.alarmID = ""
          }
      }

Developer Footer

  • 视频
  • WWDC25
  • 使用 AlarmKit API 实现唤醒功能
  • 打开菜单 关闭菜单
    • iOS
    • iPadOS
    • macOS
    • Apple tvOS
    • visionOS
    • watchOS
    打开菜单 关闭菜单
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    打开菜单 关闭菜单
    • 辅助功能
    • 配件
    • App 扩展
    • App Store
    • 音频与视频 (英文)
    • 增强现实
    • 设计
    • 分发
    • 教育
    • 字体 (英文)
    • 游戏
    • 健康与健身
    • App 内购买项目
    • 本地化
    • 地图与位置
    • 机器学习
    • 开源资源 (英文)
    • 安全性
    • Safari 浏览器与网页 (英文)
    打开菜单 关闭菜单
    • 完整文档 (英文)
    • 部分主题文档 (简体中文)
    • 教程
    • 下载 (英文)
    • 论坛 (英文)
    • 视频
    打开菜单 关闭菜单
    • 支持文档
    • 联系我们
    • 错误报告
    • 系统状态 (英文)
    打开菜单 关闭菜单
    • Apple 开发者
    • App Store Connect
    • 证书、标识符和描述文件 (英文)
    • 反馈助理
    打开菜单 关闭菜单
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program (英文)
    • News Partner Program (英文)
    • Video Partner Program (英文)
    • 安全赏金计划 (英文)
    • Security Research Device Program (英文)
    打开菜单 关闭菜单
    • 与 Apple 会面交流
    • Apple Developer Center
    • App Store 大奖 (英文)
    • Apple 设计大奖
    • Apple Developer Academies (英文)
    • WWDC
    获取 Apple Developer App。
    版权所有 © 2025 Apple Inc. 保留所有权利。
    使用条款 隐私政策 协议和准则