View in English

  • Global Nav Open Menu Global Nav Close Menu
  • Apple Developer
Search
Cancel
  • Apple Developer
  • News
  • Discover
  • Design
  • Develop
  • Distribute
  • Support
  • Account
Only search within “”

Quick Links

5 Quick Links

Vidéos

Ouvrir le menu Fermer le menu
  • Collections
  • Sujets
  • Toutes les vidéos
  • À propos

Plus de vidéos

  • À propos
  • Résumé
  • Transcription
  • Code
  • Optimisez vos alarmes avec l’API AlarmKit

    Bip bip bip ! Des minuteurs de votre app de recettes aux alarmes de réveil de votre app de voyage, le framework AlarmKit d'iOS et d'iPadOS 26 affiche les minuteurs et alarmes sur l'écran verrouillé, Dynamic Island et bien plus encore. Découvrez comment créer et gérer les alarmes de votre app, personnaliser leurs activités en temps réel et proposer des actions d'alerte personnalisées à l'aide du framework App Intents. Pour tirer le meilleur parti de cette vidéo, nous vous recommandons de regarder d'abord « Découvrez ActivityKit » de la WWDC23.

    Chapitres

    • 0:00 - Bienvenue
    • 0:32 - Aperçu
    • 1:39 - Autorisation
    • 3:06 - Création
    • 16:32 - Cycle de vie

    Ressources

    • ActivityKit
    • AlarmKit
    • App Intents
    • Creating your first app intent
    • Human Interface Guidelines: Live Activities
    • Scheduling an alarm with AlarmKit
      • Vidéo HD
      • Vidéo SD

    Vidéos connexes

    WWDC25

    • Apprenez à connaître App Intents

    WWDC23

    • Meet ActivityKit
  • Rechercher dans cette vidéo…

    Bonjour, je m’appelle Anton, ingénieur au sein de l’équipe System Experience. Vous découvrirez ici AlarmKit, un framework permettant de créer des alarmes dans votre app. Je vais d’abord vous expliquer l’expérience que vous pouvez créer avec AlarmKit, puis j’aborderai comment permettre à votre app d’autoriser l’utilisation de ce framework, comment créer une alarme et comment gérer son cycle de vie. Commençons par l’expérience. Une alarme est une alerte signalant un événement ayant lieu à une heure fixe et prédéterminée. Elle se base sur un calendrier ou un compte à rebours. Lorsque l’alerte se déclenche, elle supplante le mode silencieux et la sélection active.

    Lors de l’alerte, l’utilisateur reçoit le titre de l’alarme personnalisée, ainsi que le nom de votre app. Il peut arrêter l’alerte ou la reporter à l’aide d’un bouton facultatif.

    Une alarme peut avoir un bouton personnalisé dont l’action est définie par un app intent.

    Les alarmes fonctionnent aussi dans d’autres expériences, comme le mode veille et sur Apple Watch, si le système est jumelé à l’iPhone lors du déclenchement de l’alarme.

    Les alarmes utilisent une interface de compte à rebours personnalisée avec les Activités en temps réel fournies par votre app. Vous pouvez les voir sur l’écran verrouillé, dans Dynamic Island et dans le mode veille.

    Les utilisateurs peuvent activer les alarmes pour chaque app sur leur appareil. Maintenant que vous savez ce qu’est une alarme, voyons comment permettre aux utilisateurs d’autoriser votre app à programmer des alarmes.

    Avant qu’une app puisse programmer des alarmes, les utilisateurs doivent donner leur consentement. Vous pouvez demander l’autorisation manuellement. Sinon, elle sera demandée automatiquement lors de la création de la première alarme. Les utilisateurs peuvent à tout moment modifier le statut de leur autorisation dans l’app Réglages. La configuration de l’autorisation est simple. Ajoutez NSAlarmKitUsageDescription au fichier info.plist de votre app en expliquant votre cas d’utilisation. Expliquez brièvement le fonctionnement des alarmes dans votre app pour aider les utilisateurs à prendre la meilleure décision. Pour demander une autorisation manuellement, utilisez l’API requestAuthorization d’AlarmManager. Si aucun choix n’a encore été fait, une invite s’affiche avec une description de l’utilisation.

    Pour vérifier l’état de l’autorisation avant de programmer une alarme, interrogez authorizationState dans la classe AlarmManager.

    Dans ce cas, s’il n’est pas défini, je peux demander l’autorisation manuellement. Si l’autorisation est accordée, je peux procéder à la programmation de l’alarme. Si l’autorisation est refusée, indiquez clairement dans l’interface de l’app que l’alarme ne sera pas programmée. Maintenant que vous savez comment configurer l’autorisation des alarmes, voyons comment créer une alarme. Pour créer une alarme, vous devez définir la durée du compte à rebours, un calendrier avec une date précise ou des dates récurrentes, la configuration de l’apparence, la gestion des actions personnalisées et le son associé.

    Commençons par la durée du compte à rebours. Une alarme peut utiliser un compte à rebours avant et après l’alerte. Lorsque vous la programmez pour la première fois, l’interface utilisateur montre la durée du compte à rebours avant l’alerte. Une fois cette durée écoulée, l’alarme se déclenche et affiche l’interface de l’alerte, personnalisée avec votre configuration.

    Si l’alarme est reportée, l’interface du compte à rebours apparaît à nouveau pour la durée post-alerte.

    Une fois cette durée écoulée, l’alarme se redéclenche et peut être reportée ou fermée.

    Dans cet exemple, je configure une minuterie avec une durée avant alerte de 10 minutes. Si l’alerte est reportée, elle lancera un compte à rebours post-alerte de 5 minutes et se déclenchera à nouveau. Lors de la création d’une alarme, vous pouvez aussi fournir un calendrier fixe ou relatif.

    Un calendrier fixe spécifie une date future à laquelle l’alarme se déclenchera. Ce calendrier est absolu et ne change pas lorsque le fuseau horaire de l’appareil change. Dans cet exemple, je configure une alarme pour la Keynote WWDC. Je crée les composants de date pour le 9 juin à 9 h 41. J’utilise ensuite ces composants pour créer la date.

    Ensuite, je transfère la date au calendrier d’alarme à l’aide de son initialiseur fixe. Je peux spécifier un calendrier relatif pour mon alarme. Cela inclut l’heure du jour et toute récurrence hebdomadaire éventuelle. Ce calendrier tient compte des changements de fuseau horaire.

    Je règle ici l’alarme pour qu’elle sonne à 7 h tous les lundis, mercredis et vendredis. Je définis les sections heures et minutes, et spécifie l’occurrence quotidienne.

    Maintenant que vous savez programmer une alarme, voyons comment personnaliser son apparence. Divers éléments peuvent être personnalisés. Je veux créer un minuteur de cuisson dans mon app et personnaliser l’apparence de l’alerte à son déclenchement. Je commence par créer le bouton d’alerte à l’aide de la structure AlarmButton. Elle permet de définir le texte, la couleur de texte et l’image système du bouton.

    Je l’utilise pour définir le bouton d’arrêt, qui s’intitulera « Fermer », et s’écrira en blanc.

    Il aura également un symbole SF, qui sera utilisé lorsque l’alerte s’affichera dans Dynamic Island.

    Créons maintenant la présentation de l’alerte et le titre de l’alarme pour indiquer que la nourriture est prête. J’ajoute le bouton d’arrêt que je viens de créer. Puis, je vais créer les attributs d’alarme. Ces informations sont nécessaires pour afficher la présentation de l’alarme. Je transfère cette présentation via le paramètre correspondant. Enfin, je crée une configuration d’alarme. Tous ces éléments sont nécessaires pour programmer une alarme, y compris une durée de compte à rebours, un calendrier et les attributs. Je transmets ces attributs à la configuration de l’alarme.

    J’ai maintenant configuré la présentation de l’alerte avec le bouton Fermer.

    Si l’alarme doit juste afficher une alerte, ces étapes suffisent pour configurer son apparence. Mais pour afficher une interface de compte à rebours, des étapes supplémentaires sont nécessaires. Passons-les en revue avec mon minuteur de cuisson. J’ajoute d’abord un bouton Répéter pour déclencher un compte à rebours.

    Pour ce faire, j’utilise la structure AlarmButton et je définis le titre Répéter. Je spécifie une couleur de texte blanche et une icône de répétition, qui apparaîtra lorsque l’alarme se déclenchera dans Dynamic Island.

    Lorsque je crée la présentation de l’alerte, j’inclus donc aussi le bouton Répéter.

    Le paramètre de comportement secondaryButton spécifie si le bouton secondaire fait passer l’alarme à l’état de compte à rebours, comme pour relancer un minuteur ou reporter une alarme, ou s’il exécute une action personnalisée. Lorsqu’un utilisateur touche le bouton Répéter, je veux que l’alerte active un compte à rebours. Pour ce faire, je définis secondaryButtonBehavior sur countdown. Comme avant, je vais créer les attributs de l’alarme avec la présentation de l’alerte, puis sa configuration avec ces attributs. J’ai ajouté le bouton Répéter à l’alerte, qui lancera un compte à rebours. Pour afficher son interface utilisateur, je dois implémenter une activité en temps réel. Si l’alarme comprend la fonctionnalité de compte à rebours, elle doit l’implémenter avec une activité en temps réel. C’est ce que je vais faire. Je crée un compte à rebours pour savoir quand la nourriture sera prête. Il apparaîtra sur l’écran verrouillé, dans Dynamic Island et en mode veille.

    Si vous savez créer une activité en temps direct, vous savez créer une interface personnalisée pour le compte à rebours. Ajoutez juste l’Activité en temps réel du compte à rebours à l’extension widget de l’app.

    Si vous n’en avez pas, pas de soucis ! Regardez la vidéo « Meet ActivityKit » de la WWDC23 pour faire vos premiers pas. Configurez ensuite une activité et spécifiez les attributs de l’alarme avec le type de métadonnées.

    Je peux ici configurer une activité et spécifier qu’elle utilisera les attributs de l’alarme et mes métadonnées CookingData. Concentrons-nous sur l’écran verrouillé. Le compte à rebours de l’alarme peut être en mode compte à rebours ou en pause. Je vais fournir une vue appropriée pour chaque mode.

    Pour ce faire, je vérifie le mode actuel de l’alarme dans l’objet contextuel et j’affiche la vue appropriée.

    Je commence par fournir la vue du mode compte à rebours. Puis, je fournis ma vue pour le mode pause. Configurons maintenant les régions étendues de l’apparence de Dynamic Island. Elles contiennent le titre de l’alarme, le compte à rebours et les boutons. Puis, je configure les vues Dynamic Island compactes et minimales. Elles contiendront le compte à rebours et une icône de l’alarme. Maintenant que j’ai configuré le compte à rebours de base, j’aimerais ajouter une icône pour indiquer le mode de cuisson. Je peux fournir cette information dans les métadonnées de l’alarme. My CookingData est une structure conforme au protocole AlarmMetadata. Je définis une énumération de chaîne pour spécifier le mode de cuisson et inclure Friture et Grillades comme options. Je crée ensuite une propriété pour stocker le mode de cuisson. Les métadonnées de cuisson sont prêtes. Lors de la programmation de l’alarme dans mon app, je crée l’objet Données de cuisson et spécifie Friture comme mode de cuisson. J’inclus ensuite ces métadonnées personnalisées lors de la création des attributs.

    Dans l’Activité en temps réel, j’accède au mode de cuisson de mes métadonnées personnalisées à l’aide des attributs de contexte.

    Je peux ensuite utiliser le mode de cuisson pour créer une icône. L’affichage du compte à rebours présente maintenant l’icône Friture que j’ai générée avec le mode de cuisson de mes métadonnées. Je l’utilise sur l’écran de verrouillage et dans Dynamic Island.

    J’ai donc configuré le compte à rebours de l’alarme à l’aide d’une activité en temps réel. J’ai créé une icône personnalisée pour le compte à rebours avec les métadonnées de l’alarme.

    Si l’alarme comprend la fonctionnalité de compte à rebours, le système garantit l’affichage d’une interface de compte à rebours. L’Activité en temps réel ne peut pas toujours être affichée, notamment après le redémarrage de l’appareil et avant son premier déverrouillage. Dans ce cas, vous pouvez personnaliser la présentation système du compte à rebours. Je vais maintenant la configurer pour mon alarme de cuisson. D’abord, je définis le bouton Pause à l’aide de la structure AlarmButton. Et je l’associe à une icône système.

    Je crée la présentation, je définis le titre indiquant que la nourriture est en train de cuire, et j’ajoute le bouton Pause.

    Maintenant que j’ai défini la présentation du compte à rebours, je vais l’inclure dans les attributs. Comme mon alarme inclut la fonctionnalité de mise en pause, je vais configurer la présentation système du compte à rebours pour ce mode. Si mon compte à rebours est mis en pause, l’utilisateur doit pouvoir le relancer. D’abord, je définis le bouton Reprendre avec la structure AlarmButton. Et je l’associe à une icône de lecture.

    Je crée ensuite la présentation en mode pause avec un titre indiquant que la cuisson est en pause. J’ajoute aussi le bouton Reprendre.

    Je peux désormais ajouter la présentation en mode pause aux attributs. J’ai donc défini les présentations d’alerte, de compte à rebours et en mode pause. Parlons un instant de la gamme de couleurs. Elle est utilisée tout au long de ces présentations et permet d’associer l’alarme à votre app. Je l’ajoute dans les attributs de l’alarme. Dans la présentation d’alerte, elle définit la couleur de remplissage du bouton secondaire.

    Sur l’écran de verrouillage, elle définit la couleur du symbole sur le bouton secondaire, du titre de l’alarme et du compte à rebours. De même, elle est utilisée dans Dynamic Island. Maintenant que vous savez configurer l’apparence de l’alarme, passons à la personnalisation de ses actions. AlarmKit vous permet d’exécuter votre code quand quelqu’un touche un bouton d’alarme. Pour ce faire, vous pouvez utiliser un app intent. Vous pouvez fournir un app intent personnalisé pour le bouton d’arrêt ou le bouton secondaire. Créons un bouton secondaire personnalisé qui exécutera un app intent ouvrant mon app en cas de toucher. Pour ce faire, je vais devoir modifier l’apparence de l’alerte. D’abord, je crée un bouton Ouvrir avec la structure AlarmButton. Il s’intitulera Ouvrir, affichera le texte en blanc et une icône de flèche dans Dynamic Island.

    Lorsque je crée la présentation de l’alerte, j’inclus le bouton Ouvrir comme bouton secondaire.

    Pour que ce bouton exécute une action personnalisée, je vais remplacer le comportement du bouton secondaire par personnalisé.

    Mon bouton secondaire personnalisé est prêt. Configurons une action avec un app intent pour ouvrir l’app en cas de toucher. Voici l’app intent Ouvrir que j’aimerais utiliser. Il inclut l’identifiant d’alarme impliquant un toucher du bouton. Il définit aussi l’indicateur openAppWhenRun sur true pour indiquer que je veux que mon app s’ouvre à l’exécution de l’intent. Une fois l’app ouverte, je peux effectuer d’autres tâches, comme afficher une vue détaillée de l’alarme avec cet identifiant. Utilisons l’intent que je viens de créer. Lors de la programmation de l’alarme, je crée un identifiant unique qui me permet de la suivre après sa création. Je crée une instance de l’intent OpenInApp et transmets l’identifiant unique de l’alarme.

    Lors de la configuration de l’alarme, j’inclus l’intent secondaire pour indiquer que c’est l’intent à exécuter si le bouton secondaire est touché.

    J’ai ajouté un bouton Ouvrir personnalisé, défini un app intent pour ouvrir l’app et indiqué au système d’exécuter cet intent si le bouton secondaire est touché. Voyons maintenant comment configurer le son de l’alarme. Si vous ne spécifiez pas de paramètre sonore, l’alarme utilise un son système par défaut. Mais vous pouvez personnaliser le son de l’alarme. Comme AlarmKit utilise ActivityKit pour la présentation de l’alarme, vous pouvez personnaliser le son avec sa structure AlertSound.

    Vous devrez spécifier le nom du fichier audio, joint au bundle principal de l’app ou dans le dossier Library/Sounds de son conteneur de données. Une fois que vous avez terminé de configurer l’alarme, vous pouvez la gérer dans le système. Utilisez la classe AlarmManager à cet effet. Après avoir configuré l’alarme, je peux la programmer avec le système. Pour ce faire, j’utilise l’identifiant unique de l’alarme et la configuration que j’ai créée. Cet identifiant permet de suivre l’alarme tout au long de son cycle de vie.

    Vous avez le contrôle total du cycle de vie de l’alarme. Vous pouvez la faire passer en mode compte à rebours, l’annuler, l’arrêter, l’interrompre ou la reprendre.

    J’aimerais vous donner quelques conseils pour utiliser AlarmKit. Les alarmes sont idéales pour les comptes à rebours avec un intervalle spécifique, comme une minuterie de cuisson, ou les alertes récurrentes, comme une alarme de réveil. Elles ne remplacent pas d’autres notifications clés, comme les alertes critiques ou les notifications urgentes.

    Visez la clarté dans la présentation de l’alerte. Les alertes s’affichent de manière proéminente. Vous devez donc clairement indiquer la nature de l’alarme et les actions possibles.

    Si l’alarme inclut un compte à rebours, envisagez d’en ajouter les éléments clés dans l’Activité en temps réel. Cela inclut la durée restante, un bouton de fermeture et un bouton de pause ou de reprise. Aujourd’hui, vous avez appris à utiliser AlarmKit pour créer des alarmes et gérer leur cycle de vie dans le système. Vous pouvez maintenant l’utiliser dans votre app. Utilisez AlarmKit afin de configurer des alarmes pour les cas d’utilisation de votre app. Créez des comptes à rebours personnalisées sur l’écran verrouillé et dans Dynamic Island avec les Activités en temps réel. Ajoutez des actions personnalisées aux alarmes avec les app intents.

    Notre session est terminée. Merci de votre participation.

    • 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 = ""
          }
      }
    • 0:00 - Bienvenue
    • AlarmKit est un nouveau framework qui vous permet de créer des minuteurs et des alarmes. Familiarisez-vous avec l’expérience, l’obtention d’une autorisation, la création d’alarmes et la gestion de leur cycle de vie.

    • 0:32 - Aperçu
    • Les alarmes sont des alertes programmées qui supplantent le mode silencieux et affichent un titre et un nom d’app personnalisés. Elles peuvent également afficher un compte à rebours. Les utilisateurs peuvent arrêter l’alarme, la reporter ou interagir avec des boutons personnalisés. Les alarmes sont visibles sur l’écran verrouillé, dans Dynamic Island, en mode veille et sur l’Apple Watch. Les utilisateurs doivent activer cette fonctionnalité pour chaque app.

    • 1:39 - Autorisation
    • Pour activer la programmation des alarmes dans une app, les utilisateurs doivent l’autoriser. Cela peut se faire automatiquement lors de la création de la première alarme ou manuellement via l’API requestAuthorization d’AlarmManager. Pour expliquer le mode d’utilisation des alarmes, vous devez ajouter 'NSAlarmKitUsageDescription' au fichier Info.plist. Les utilisateurs peuvent modifier le statut d’autorisation dans Réglages. Avant de programmer une alarme, l’app peut vérifier l’état de l’autorisation. En cas de refus, elle doit informer les utilisateurs qu’aucune alarme ne sera programmée.

    • 3:06 - Création
    • La création d’une alarme implique plusieurs éléments clés. Tout d’abord, l’alarme peut être réglée avec une durée de compte à rebours, qui peut inclure à la fois un intervalle de pré-alerte et de post-alerte. Lorsque l’alarme est planifiée avec un compte à rebours, une interface utilisateur de compte à rebours s’affiche pour la durée de pré-alerte. Une fois cette durée écoulée, l’alarme se déclenche, affichant une interface utilisateur d’alerte personnalisée. Si l’alarme est reportée, l’interface utilisateur du compte à rebours réapparaît pendant l’intervalle de post-alerte avant de se déclenche à nouveau. Les alarmes peuvent être programmées à l’aide d’un calendrier fixe ou relatif. Un calendrier fixe spécifie une date et une heure futures précises, tandis qu’un calendrier relatif permet dé définir une heure quotidienne de la journée avec un modèle de récurrence hebdomadaire facultatif, garantissant que l’alarme s’ajuste correctement aux changements de fuseau horaire. En plus de la programmation, vous pouvez personnaliser l’apparence de l’alarme. Cela inclut la création et la configuration de boutons d’alerte, tels qu’un bouton « Ignorer », et la définition du titre de l’alarme. Pour les alarmes avec une fonctionnalité de compte à rebours, vous pouvez aussi ajouter un bouton « Répéter ». La présentation et les attributs de l’alerte sont ensuite définis pour spécifier l’apparence et le comportement de l’alarme lorsqu’elle se déclenche. Si une alarme inclut une fonctionnalité de compte à rebours, vous devez implémenter une Activité en direct pour afficher l’interface du compte à rebours sur l’écran verrouillé, dans Dynamic Island et en mode veille. Cela implique de créer une interface personnalisée pour le compte à rebours et de configurer une 'ActivityConfiguration' avec les attributs d’alarme appropriés. L’Activité en direct peut afficher différentes vues selon que le compte à rebours est actif ou suspendu, offrant ainsi une expérience utilisateur fluide selon les états de l’appareil. L’exemple présente des métadonnées personnalisées pour transmettre des informations supplémentaires à l’activité en direct. Ces métadonnées incluent une énumération personnalisée, qui permet à l’alarme d’afficher une icône basée sur la valeur de l’énumération à la fois sur l’écran verrouillé et dans Dynamic Island pendant le compte à rebours. La session décrit comment créer des App Intents personnalisés pour exécuter du code spécifique en cas de pression sur un bouton, comme lors de l’ouverture de l’app. Elle décrit également comment configurer le son de l’alarme, permettant aux utilisateurs de choisir un son personnalisé ou d’utiliser le son système par défaut.

    • 16:32 - Cycle de vie
    • AlarmKit permet aux utilisateurs de créer, programmer et gérer des alarmes à l’aide de la classe 'AlarmManager'. Les alarmes peuvent être configurées, suivies via des identifiants uniques et mises dans différents états (compte à rebours, pause, arrêt, etc.). En règle générale; il est conseillé d’utiliser des alarmes pour les comptes à rebours et les alertes récurrentes, de veiller à une présentation claire des alertes et d’inclure toutes les informations et actions essentielles dans l’Activité en direct du compte à rebours.

Developer Footer

  • Vidéos
  • WWDC25
  • Optimisez vos alarmes avec l’API AlarmKit
  • Open Menu Close Menu
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    Open Menu Close Menu
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • Icon Composer
    • SF Symbols
    Open Menu Close Menu
    • Accessibility
    • Accessories
    • App Store
    • Audio & Video
    • Augmented Reality
    • Business
    • Design
    • Distribution
    • Education
    • Fonts
    • Games
    • Health & Fitness
    • In-App Purchase
    • Localization
    • Maps & Location
    • Machine Learning & AI
    • Open Source
    • Security
    • Safari & Web
    Open Menu Close Menu
    • Documentation
    • Sample Code
    • Tutorials
    • Downloads
    • Forums
    • Videos
    Open Menu Close Menu
    • Support Articles
    • Contact Us
    • Bug Reporting
    • System Status
    Open Menu Close Menu
    • Apple Developer
    • App Store Connect
    • Certificates, IDs, & Profiles
    • Feedback Assistant
    Open Menu Close Menu
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program
    • News Partner Program
    • Video Partner Program
    • Security Bounty Program
    • Security Research Device Program
    Open Menu Close Menu
    • Meet with Apple
    • Apple Developer Centers
    • App Store Awards
    • Apple Design Awards
    • Apple Developer Academies
    • WWDC
    Get the Apple Developer app.
    Copyright © 2025 Apple Inc. All rights reserved.
    Terms of Use Privacy Policy Agreements and Guidelines