Passer au contenu

Activités en direct pour Swift

Découvrez comment implémenter les activités en direct pour le SDK Swift de Braze. Les activités en direct sont des notifications persistantes et interactives qui s’affichent directement sur l’écran de verrouillage, permettant aux utilisateurs d’obtenir des mises à jour dynamiques en temps réel—sans déverrouiller leur appareil.

Fonctionnement

Une activité en direct de suivi de livraison sur l’écran de verrouillage d’un iPhone. Une barre de statut avec une voiture est remplie presque à moitié. Le texte indique « 2 min avant le retrait »

Les activités en direct présentent à la fois des informations statiques et des informations dynamiques que vous mettez à jour. Par exemple, vous pouvez créer une activité en direct qui sert de suivi de statut pour une livraison. Cette activité en direct affiche le nom de votre entreprise comme information statique, ainsi qu’un « Délai de livraison » dynamique qui se met à jour à mesure que le livreur approche de sa destination.

En tant que développeur, vous pouvez utiliser Braze pour gérer le cycle de vie de vos activités en direct, appeler la REST API de Braze pour mettre à jour vos activités en direct, et faire en sorte que tous les appareils abonnés reçoivent la mise à jour le plus rapidement possible. De plus, comme vous gérez vos activités en direct via Braze, vous pouvez les utiliser conjointement avec vos autres canaux de communication (notifications push, messages in-app, Content Cards) pour favoriser leur adoption.

Diagramme de séquence

Afficher le diagramme
---
config:
  theme: mc
---
sequenceDiagram
  participant Server as Client Server
  participant Device as User Device
  participant App as iOS App / Braze SDK
  participant BrazeAPI as Braze API
  participant APNS as Apple Push Notification Service
  Note over Server, APNS: Launch Option 1<br/>Locally Start Activities
  App ->> App: Register a Live Activity using <br>`launchActivity(pushTokenTag:activity:)`
  App ->> App: Get push token from iOS
  App ->> BrazeAPI: Activity ID & Push token<br>automatically sent to Braze
  Note over Server, APNS: Launch Option 2<br/>Remotely Start Activities
  Device ->> App: Call `registerPushToStart`<br>to collect push tokens early
  App ->> BrazeAPI: Push-to-start tokens sent to Braze
  Server ->> BrazeAPI: POST /messages/live_activity/start
  Note right of BrazeAPI: Payload includes:<br>- push_token<br>- activity_id<br>- external_id<br>- event_name<br>- content_state (optional)
  BrazeAPI ->> APNS: Live activity start request
  APNS ->> Device: APNS sends activity to device
  App ->> App: Get push token from iOS
  App ->> BrazeAPI: Activity ID & Push token<br>automatically sent to Braze
  Note over Server, APNS: Resuming activities upon app launch
  App ->> App: Call `resumeActivities(ofType:)` on each app launch
  Note over Server, APNS: Updating a Live Activity
  loop update a live activity
  Server ->> BrazeAPI: POST /messages/live_activity/update
  Note right of BrazeAPI: Payload includes changes<br>to ContentState (dynamic variables)
  BrazeAPI ->> APNS: Update sent to APNS
  APNS ->> Device: APNS sends update to device
  end
  Note over Server, APNS: Ending a Live Activity
  Server ->> BrazeAPI: POST /messages/live_activity/update
  Note right of BrazeAPI: Activity can be ended via:<br> - User manually dismisses<br>- Times out after 12 hours<br>- Setting `end_activity: true` on `/messages/live_activity/update`
  APNS ->> Device: Live activity is dismissed

Mise en œuvre d’une activité en direct

Conditions préalables

Avant de pouvoir utiliser cette fonctionnalité, vous devrez intégrer le SDK Braze Swift. Vous devrez également effectuer les étapes suivantes :

  • Assurez-vous que votre projet cible iOS 16.1 ou une version ultérieure.
  • Ajoutez l’autorisation Push Notification sous Signing & Capabilities dans votre projet Xcode.
  • Assurez-vous d’utiliser des clés .p8 pour envoyer les notifications. Les anciens fichiers, comme .p12 ou .pem, ne sont pas pris en charge.
  • À partir de la version 8.2.0 du SDK Swift de Braze, vous pouvez enregistrer une activité en direct à distance. Cette fonctionnalité nécessite iOS 17.2 ou une version ultérieure.

Étape 1 : Créer une activité

Commencez par suivre la page Displaying live data with Live Activities de la documentation d’Apple pour configurer les activités en direct dans votre application iOS. Dans le cadre de cette tâche, veillez à inclure NSSupportsLiveActivities défini sur YES dans votre fichier Info.plist.

Comme la nature exacte de votre activité en direct dépend de votre cas d’usage métier, configurez et initialisez les objets Activity. Définissez notamment :

  • ActivityAttributes : ce protocole définit le contenu statique (qui ne change pas) et dynamique (qui change) affiché dans votre activité en direct.
  • ActivityAttributes.ContentState : ce type définit les données dynamiques qui sont mises à jour au cours de l’activité.

Vous utilisez également SwiftUI pour créer la présentation de l’interface utilisateur de l’écran verrouillé et de la Dynamic Island sur les appareils compatibles.

Familiarisez-vous avec les conditions préalables et limitations d’Apple concernant les activités en direct, car ces contraintes sont indépendantes de Braze.

Exemple

Imaginons que nous souhaitions créer une activité en direct pour informer nos utilisateurs de l’évolution du Superb Owl, une compétition dans laquelle deux centres de sauvegarde de la faune s’affrontent et marquent des points en fonction des chouettes qu’ils hébergent. Pour cet exemple, nous avons créé une structure appelée SportsActivityAttributes, mais vous pouvez utiliser votre propre implémentation de ActivityAttributes.

#if canImport(ActivityKit)
  import ActivityKit
#endif

@available(iOS 16.1, *)
struct SportsActivityAttributes: ActivityAttributes {
  public struct ContentState: Codable, Hashable {
    var teamOneScore: Int
    var teamTwoScore: Int
  }

  var gameName: String
  var gameNumber: String
}

Étape 2 : Démarrer l’activité

Choisissez d’abord comment vous souhaitez enregistrer votre activité :

  • À distance : utilisez la méthode registerPushToStart tôt dans le cycle de vie de l’utilisateur et avant d’avoir besoin du jeton push-to-start, puis démarrez une activité à l’aide de l’endpoint /messages/live_activity/start.
  • En local : créez une instance de votre activité en direct, puis utilisez la méthode launchActivity pour créer des jetons push que Braze gérera.

Étape 2.1 : Ajouter BrazeKit à votre extension de widget

Dans votre projet Xcode, sélectionnez le nom de votre application, puis General. Sous Frameworks and Libraries, vérifiez que BrazeKit figure dans la liste.

Le framework BrazeKit sous Frameworks and Libraries dans un exemple de projet Xcode.

Étape 2.2 : Ajouter le protocole BrazeLiveActivityAttributes

Dans votre implémentation de ActivityAttributes, ajoutez la conformité au protocole BrazeLiveActivityAttributes, puis ajoutez la propriété brazeActivityId à votre modèle d’attributs.

import BrazeKit

#if canImport(ActivityKit)
  import ActivityKit
#endif

@available(iOS 16.1, *)
// 1. Add the `BrazeLiveActivityAttributes` conformance to your `ActivityAttributes` struct.
struct SportsActivityAttributes: ActivityAttributes, BrazeLiveActivityAttributes {
  public struct ContentState: Codable, Hashable {
    var teamOneScore: Int
    var teamTwoScore: Int
  }

  var gameName: String
  var gameNumber: String

  // 2. Add the `String?` property to represent the activity ID.
  var brazeActivityId: String?
}

Étape 2.3 : S’enregistrer pour le push-to-start

Ensuite, enregistrez le type d’activité en direct afin que Braze puisse suivre tous les jetons push-to-start et toutes les instances d’activité en direct associés à ce type.

Exemple

Dans l’exemple suivant, la classe LiveActivityManager gère les objets d’activité en direct. La méthode registerPushToStart enregistre ensuite SportsActivityAttributes :

import BrazeKit

#if canImport(ActivityKit)
  import ActivityKit
#endif

class LiveActivityManager {

  @available(iOS 17.2, *)
  func registerActivityType() {
    // This method returns a Swift background task.
    // You may keep a reference to this task if you need to cancel it wherever appropriate, or ignore the return value if you wish.
    let pushToStartObserver: Task = Self.braze?.liveActivities.registerPushToStart(
      forType: Activity<SportsActivityAttributes>.self,
      name: "SportsActivityAttributes"
    )
  }

}

Étape 2.4 : Envoyer une notification push-to-start

Envoyez une notification push-to-start à distance à l’aide de l’endpoint /messages/live_activity/start.

Vous pouvez utiliser le framework ActivityKit d’Apple pour obtenir un jeton push, que le SDK de Braze peut gérer pour vous. Vous pouvez ainsi mettre à jour les activités en direct via l’API de Braze, puisque Braze envoie le jeton push au service de notification push d’Apple (APNs) en arrière-plan.

  1. Créez une instance de votre implémentation d’activité en direct à l’aide des API ActivityKit d’Apple.
  2. Définissez le paramètre pushType sur .token.
  3. Transmettez les ActivitiesAttributes et ContentState de l’activité en direct que vous avez définis.
  4. Enregistrez votre activité auprès de votre instance Braze en la transmettant à launchActivity(pushTokenTag:activity:). Le paramètre pushTokenTag est une chaîne de caractères personnalisée que vous définissez. Elle doit être unique pour chaque activité en direct que vous créez.

Une fois l’activité en direct enregistrée, le SDK de Braze extrait les jetons push et surveille leurs modifications.

Exemple

Pour notre exemple, créez une classe appelée LiveActivityManager qui servira d’interface pour nos objets d’activité en direct. Définissez ensuite pushTokenTag sur "sports-game-2024-03-15".

import BrazeKit

#if canImport(ActivityKit)
  import ActivityKit
#endif

class LiveActivityManager {

  @available(iOS 16.2, *)
  func createActivity() {
    let activityAttributes = SportsActivityAttributes(gameName: "Superb Owl", gameNumber: "Game 1")
    let contentState = SportsActivityAttributes.ContentState(teamOneScore: "0", teamTwoScore: "0")
    let activityContent = ActivityContent(state: contentState, staleDate: nil)
    if let activity = try? Activity.request(attributes: activityAttributes,
                                            content: activityContent,
      // Setting your pushType as .token allows the Activity to generate push tokens for the server to watch.
                                            pushType: .token) {
      // Register your Live Activity with Braze using the pushTokenTag.
      // This method returns a Swift background task.
      // You may keep a reference to this task if you need to cancel it wherever appropriate, or ignore the return value if you wish.
      let liveActivityObserver: Task = AppDelegate.braze?.liveActivities.launchActivity(pushTokenTag: "sports-game-2024-03-15",
                                                                                        activity: activity)
    }
  }

}

Votre widget d’activité en direct affiche ce contenu initial à vos utilisateurs.

Une activité en direct sur l’écran verrouillé d’un iPhone affichant les scores de deux équipes. Wild Bird Fund et Owl Rehab ont toutes deux un score de 0.

Étape 3 : Reprendre le suivi de l’activité

Pour que Braze suive votre activité en direct au lancement de l’application :

  1. Ouvrez votre fichier AppDelegate.
  2. Importez le module ActivityKit s’il est disponible.
  3. Appelez resumeActivities(ofType:) dans application(_:didFinishLaunchingWithOptions:) pour tous les types ActivityAttributes que vous avez enregistrés dans votre application.

Braze peut ainsi reprendre les tâches de suivi des mises à jour des jetons push pour toutes les activités en direct actives. Notez que si un utilisateur a explicitement fermé l’activité en direct sur son appareil, celle-ci est considérée comme supprimée et Braze cesse de la suivre.

Exemple

import UIKit
import BrazeKit

#if canImport(ActivityKit)
  import ActivityKit
#endif

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

  static var braze: Braze? = nil

  func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {

    if #available(iOS 16.1, *) {
      Self.braze?.liveActivities.resumeActivities(
        ofType: Activity<SportsActivityAttributes>.self
      )
    }

    return true
  }
}

Étape 4 : Mettre à jour l’activité

Une activité en direct sur l’écran verrouillé d’un iPhone affichant les scores de deux équipes. Wild Bird Fund a 2 points et Owl Rehab a 4 points.

L’endpoint /messages/live_activity/update vous permet de mettre à jour une activité en direct à l’aide de notifications push transmises via l’API REST de Braze. Utilisez cet endpoint pour mettre à jour le ContentState de votre activité en direct.

À mesure que vous mettez à jour votre ContentState, votre widget d’activité en direct affiche les nouvelles informations. Voici à quoi ressemble le Superb Owl à la fin de la première mi-temps.

Pour plus de détails, consultez notre article sur l’endpoint /messages/live_activity/update.

Étape 5 : Mettre fin à l’activité

Lorsqu’une activité en direct est active, elle s’affiche à la fois sur l’écran verrouillé de l’utilisateur et dans la Dynamic Island. Pour y mettre fin via Braze, utilisez l’endpoint /messages/live_activity/update avec end_activity défini sur true.

Pour fiabiliser la fin d’une activité en direct, vous pouvez suivre les étapes facultatives suivantes :

  1. Incluez éventuellement dismissal_date dans cette même requête update pour indiquer à iOS quand supprimer l’interface utilisateur de l’activité en direct.
  2. Vérifiez les résultats de distribution dans le journal d’activité des messages.

Planifier la fermeture automatique

Pour planifier la fermeture automatique, programmez une requête de suivi vers l’endpoint de mise à jour après avoir démarré l’activité en direct.

  1. Envoyez une requête /messages/live_activity/start avec un activity_id que vous pouvez suivre.
  2. Stockez cet activity_id et l’heure de fin cible dans le planificateur de votre backend.
  3. À l’heure de fin cible, envoyez une requête /messages/live_activity/update avec end_activity défini sur true.
  4. Configurez la date de fermeture dans cette même requête de mise à jour. Pour plus de détails, consultez l’endpoint /messages/live_activity/update.

Notez que le moment de la fermeture est contrôlé par iOS. Même après l’envoi d’une requête de fin valide, la suppression de l’écran verrouillé ou de la Dynamic Island peut être retardée ou se comporter différemment selon les conditions au niveau du système d’exploitation.

Une activité en direct peut également prendre fin en dehors de Braze :

  • Fermeture par l’utilisateur : un utilisateur peut fermer manuellement une activité en direct.
  • Expiration : après un délai par défaut de huit heures, iOS retire l’activité en direct de la Dynamic Island de l’utilisateur. Après un délai par défaut de 12 heures, iOS retire l’activité en direct de l’écran verrouillé de l’utilisateur.

Pour plus de détails, consultez notre article sur l’endpoint /messages/live_activity/update.

Suivi des activités en direct

Les événements d’activité en direct sont disponibles dans Currents, le partage de données Snowflake et le générateur de requêtes. Les événements suivants vous aident à comprendre et à surveiller le cycle de vie de vos activités en direct, à suivre la disponibilité des jetons, ainsi qu’à diagnostiquer vous-même les problèmes ou à vérifier les statuts de réception.

  • Live Activity Push To Start Token Change : enregistre l’ajout ou la mise à jour d’un jeton push-to-start (PTS) dans Braze, ce qui vous permet de suivre l’enregistrement et la disponibilité des jetons pour chaque utilisateur.
  • Live Activity Update Token Change : suit l’ajout, la mise à jour ou la suppression des jetons de mise à jour d’activité en direct (LAU).
  • Live Activity Send : consigne chaque démarrage, mise à jour ou fin d’une activité en direct par Braze.
  • Live Activity Outcome : indique le statut final de réception auprès du service Apple Push Notification (APNs) pour chaque activité en direct envoyée depuis Braze.

Vérifier les envois d’activités en direct

Pour confirmer qu’un espace de travail envoie des activités en direct iOS (Live Activities), vous pouvez utiliser les méthodes suivantes :

Journal d’activité des messages

Allez dans Paramètres > Journal d’activité des messages et filtrez les erreurs liées aux activités en direct pour consulter les résultats de réception de ces activités sur la période souhaitée. Pour plus d’informations, consultez la section Journal d’activité des messages.

Générateur de requêtes, Currents ou partage de données Snowflake

Recherchez les événements d’activité en direct suivants pour vérifier leur cycle de vie et leur réception :

  • Live Activity Send : Enregistré chaque fois qu’une activité en direct est démarrée, mise à jour ou terminée par Braze
  • Live Activity Outcome : Statut final de réception auprès d’APN pour chaque activité en direct envoyée

Vous pouvez également vérifier les signaux de disponibilité des jetons :

  • Live Activity Push To Start Token Change
  • Live Activity Update Token Change

Tableau de bord d’utilisation de l’API

Allez dans Paramètres > API et identifiants > Tableau de bord, sélectionnez Filtres, puis filtrez par Endpoint pour afficher les réponses de l’API. Par exemple, sélectionnez /messages/live_activity/update (ou /messages/live_activity/start) et consultez le volume de requêtes des 30 derniers jours. Ces réponses indiquent que l’API est appelée et que des notifications d’activités en direct iOS sont utilisées dans cet espace de travail. Pour plus d’informations, consultez la section Tableau de bord d’utilisation de l’API.

Observer les événements d’activité en direct (facultatif)

Le SDK de Braze fournit deux méthodes d’abonnement sur braze.liveActivities pour observer l’ensemble du cycle de vie des activités en direct. Pour un guide pas à pas complet, consultez le tutoriel sur les activités en direct.

  • subscribeToStateUpdates(_:) : fournit les événements du cycle de vie pour l’enregistrement des jetons push-to-start et pour les instances d’activité en cours d’exécution.
  • subscribeToErrors(_:) : fournit les erreurs côté SDK et côté serveur rencontrées lors du suivi des activités en direct.

Configurer les abonnements

Configurez les abonnements une seule fois dans application(_:didFinishLaunchingWithOptions:) et conservez-les pendant toute la durée de vie de votre application :

class AppDelegate: UIResponder, UIApplicationDelegate {
  static var braze: Braze?

  var stateSubscription: Braze.Cancellable?
  var errorSubscription: Braze.Cancellable?

  func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    let braze = Braze(configuration: config)
    Self.braze = braze

    if #available(iOS 16.1, *) {
      stateSubscription = Self.braze?.liveActivities.subscribeToStateUpdates { event in
        self.handleStateUpdate(event)
      }
      errorSubscription = Self.braze?.liveActivities.subscribeToErrors { error in
        self.handleLiveActivityError(error)
      }
    }

    return true
  }
}

subscribeToStateUpdates

subscribeToStateUpdates(_:) fournit des valeurs UpdateEvent qui couvrent l’ensemble du cycle de vie des activités en direct. Les événements sont répartis en deux portées :

  • .activityType(ActivityType) : événements au niveau du type pour l’enregistrement des jetons push-to-start (iOS 17.2+). Aucune instance d’activité n’existe encore.
  • .activityInstance(ActivityInstance) : événements au niveau de l’instance pour une activité spécifique en cours d’exécution.

Plusieurs abonnés sont pris en charge : chaque abonnement actif reçoit chaque émission de manière indépendante.

Événements au niveau du type

Événement Quand il se déclenche
.pushToStartTokenRead(activityType:) Un jeton push-to-start a été lu depuis le système d’exploitation. Braze peut désormais démarrer à distance une nouvelle activité de ce type.
.pushToStartTokenFlushed(activityType:) Le jeton a été envoyé au serveur Braze. Braze peut envoyer des notifications push-to-start pour ce type.
.pushToStartUnregistered(activityType:) Le push-to-start a été désenregistré pour ce type d’activité via unregisterPushToStart(types:completion:).
.pushToStartUnregisterFlushed(activityType:) La demande de désenregistrement a été envoyée au serveur Braze.

Événements au niveau de l’instance

Événement Quand il se déclenche
.started(activityId:activityType:pushTokenTag:launchSource:) Le SDK a commencé à suivre cette activité via launchActivity(pushTokenTag:activity:). La valeur launchSource est .local pour les activités lancées par l’application, ou .pushToStart pour les activités démarrées à distance.
.resumed(activityId:activityType:pushTokenTag:) Le SDK a repris le suivi de cette activité via resumeActivities(ofType:).
.pushTokenFlushed(activityId:activityType:pushTokenTag:) Le jeton de notification push de l’activité a été accepté par le serveur Braze.
.active(activityId:activityType:) L’activité est actuellement active et visible pour l’utilisateur.
.stale(activityId:activityType:staleDate:) Le contenu de l’activité est devenu obsolète. Émis uniquement sur iOS 16.2 et versions ultérieures.
.dismissed(activityId:activityType:) L’utilisateur a fermé manuellement l’activité.
.ended(activityId:activityType:) L’activité s’est terminée.
.contentUpdated(activityId:activityType:) L’état du contenu de l’activité a été mis à jour (iOS 16.2+). Utilisez une logique personnalisée pour rechercher l’Activity<T> par ID dans Activity.activities et accéder à l’état typé via activity.content.state.
.pushTokenUpdated(activityId:activityType:) ActivityKit a effectué une rotation du jeton de notification push de l’activité.
Exemple
func handleStateUpdate(_ event: Braze.LiveActivities.UpdateEvent) {
  switch event {

  // Type-scoped: push-to-start token lifecycle (iOS 17.2+)
  case .activityType(.pushToStartTokenRead(let activityType)):
    print("[\(activityType)] Push-to-start token read by SDK")

  // ...

  // Instance-scoped: SDK tracking
  case .activityInstance(.started(let id, let type, let tag, let source)):
    print("[\(type)] Activity \(id) started via \(source), tag: \(tag)")

  // ...

  // Instance-scoped: ActivityKit lifecycle
  case .activityInstance(.active(let id, let type)):
    print("[\(type)] Activity \(id) is active")

  // ...

  case .activityInstance(.ended(let id, let type)):
    print("[\(type)] Activity \(id) ended")

  // Instance-scoped: content updates (iOS 16.2+)
  case .activityInstance(.contentUpdated(let id, let type)):
    // For more advanced use cases of `contentUpdated`, see the section below
    print("[\(type)] Content updated for activity \(id)")

  case .activityInstance(.pushTokenUpdated(let id, let type)):
    print("[\(type)] Activity \(id) push token rotated")
  }
}

subscribeToErrors

subscribeToErrors(_:) fournit des valeurs ErrorEvent en utilisant les deux mêmes portées que UpdateEvent :

  • .activityType(ActivityType) : erreurs au niveau du type pour les échecs d’enregistrement push-to-start.
  • .activityInstance(ActivityInstance) : erreurs au niveau de l’instance pour une activité en cours d’exécution.

Utilisez l’indicateur isTransient pour déterminer si une nouvelle tentative est pertinente. Le SDK relance automatiquement les échecs transitoires.

Erreurs au niveau du type

Erreur Quand elle se déclenche
.pushToStartRegistrationFailed(activityType:isTransient:reason:) Le jeton push-to-start n’a pas pu atteindre le serveur Braze.

Erreurs au niveau de l’instance

Erreur Quand elle se déclenche
.registrationFailed(activityId:activityType:pushTokenTag:isTransient:reason:) Le jeton de notification push de l’activité n’a pas pu être enregistré auprès de Braze.
.activityNotFound(activityId:activityType:) resumeActivities(ofType:) a trouvé un mappage stocké pour une activité qui n’est plus en cours d’exécution : elle s’est probablement terminée pendant que l’application était fermée.
.invalidPushTokenTag(activityId:activityType:tag:) launchActivity(pushTokenTag:activity:) a été appelé avec une étiquette non valide. Les étiquettes doivent être non vides et faire moins de 256 octets.
Exemple
func handleLiveActivityError(_ error: Braze.LiveActivities.ErrorEvent) {
  switch error {

  // Type-scoped errors
  case .activityType(.pushToStartRegistrationFailed(let type, let isTransient, let reason)):
    if isTransient {
      print("[\(type)] Push-to-start registration failed (transient, will retry): \(reason)")
    } else {
      print("[\(type)] Push-to-start registration failed (permanent): \(reason)")
    }

  // Instance-scoped errors
  case .activityInstance(.registrationFailed(let id, let type, _, let isTransient, let reason)):
    if isTransient {
      print("[\(type)] Activity \(id) registration failed (transient, retrying): \(reason)")
    } else {
      print("[\(type)] Activity \(id) registration failed (permanent): \(reason)")
    }

  case .activityInstance(.activityNotFound(let id, let type)):
    print("[\(type)] Stored activity \(id) not found on resume")

  case .activityInstance(.invalidPushTokenTag(let id, let type, let tag)):
    print("[\(type)] Activity \(id) has invalid push token tag '\(tag)'")
  }
}

Gérer les mises à jour de l’état du contenu (facultatif)

Suivez cette section si vous souhaitez utiliser l’état du contenu de l’instance réelle de l’activité en direct.

Lorsqu’un événement .contentUpdated se déclenche, utilisez une logique personnalisée pour rechercher l’Activity<T> en cours d’exécution par son ID dans Activity.activities, puis accédez au ContentState typé via activity.content.state.

Type d’attributs unique

case .activityInstance(.contentUpdated(let id, let type)):
  #if canImport(ActivityKit)
    // Add custom logic look up the Activity<T> by ID and access your app's typed ContentState.
    // In this example, `SportsActivityAttributes` is the app's custom type.
    if #available(iOS 16.2, *),
      let activity = findActivityInstance(id: id, as: SportsActivityAttributes.self)
    {
      // `activityContent` is now strongly typed as a `SportsActivityAttributes`
      let activityContent = activity.content.state
      print("[\(type)] Game \(id) — score: \(activityContent.teamOneScore)–\(activityContent.teamTwoScore)")
      return
    }
  #endif
  print("[\(type)] Content updated for activity \(id)")

// ...

// - MARK: Helper methods

@available(iOS 16.2, *)
func findActivityInstance<Attributes: ActivityAttributes>(
  id: String,
  as type: Attributes.Type
) -> Activity<Attributes>? {
  // Use Apple's API to find the matching Live Activity instance:
  // - https://developer.apple.com/documentation/activitykit/activity/activities
  Activity<Attributes>.activities.first(where: { $0.id == id })
}

Types d’attributs multiples

Si votre application utilise plusieurs types d’ActivityAttributes, vérifiez la chaîne type pour rechercher l’Activity<T> approprié :

case .activityInstance(.contentUpdated(let id, let type)):
  #if canImport(ActivityKit)
    if #available(iOS 16.2, *) {
      if type == "SportsActivityAttributes",
        let activity = findActivityInstance(id: id, as: SportsActivityAttributes.self)
      {
        let activityContent = activity.content.state
        print("[\(type)] Game \(id) — score: \(activityContent.teamOneScore)–\(activityContent.teamTwoScore)")
        return

      } else if type == "OrderActivityAttributes",
        let activity = findActivityInstance(id: id, as: OrderActivityAttributes.self)
      {
        let activityContent = activity.content.state
        print("[\(type)] Order \(id) — status: \(activityContent.status), ETA: \(activityContent.eta)")
        return
      }
    }
  #endif
  print("[\(type)] Content updated for activity \(id)")

// ...

// - MARK: Helper methods

@available(iOS 16.2, *)
func findActivityInstance<Attributes: ActivityAttributes>(
  id: String,
  as type: Attributes.Type
) -> Activity<Attributes>? {
  // Use Apple's API to find the matching Live Activity instance:
  // - https://developer.apple.com/documentation/activitykit/activity/activities
  Activity<Attributes>.activities.first(where: { $0.id == id })
}

Foire aux questions (FAQ)

Fonctionnalité et support

Quelles plateformes prennent en charge les activités en direct ?

Actuellement, les activités en direct sont une fonctionnalité spécifique à iOS et iPadOS. Par défaut, les activités lancées sur un iPhone ou un iPad sont également affichées sur tout appareil watchOS 11+ ou macOS 26+ appairé.

Braze ne fournit pas actuellement de prise en charge native des activités en direct sur Android. Pour Android, vous pouvez créer des expériences de mise à jour en temps réel via les notifications push de Braze et le rendu de notifications personnalisées.

Capture d'écran d'une barre de menus macOS affichant une activité en direct sous forme d'alerte.

L’article sur les activités en direct couvre les conditions préalables à la gestion des activités en direct via le SDK Swift de Braze.

Les applications React Native prennent-elles en charge les activités en direct ?

Oui, le SDK React Native 3.0.0+ prend en charge les activités en direct via le SDK Swift de Braze. Autrement dit, vous devez écrire du code iOS React Native directement au-dessus du SDK Swift de Braze.

Il n’existe pas d’API JavaScript spécifique à React Native pour les activités en direct, car les fonctionnalités des activités en direct fournies par Apple utilisent des langages non transposables en JavaScript (par exemple, la concurrence Swift, les génériques, SwiftUI).

Braze prend-il en charge les activités en direct en tant que Campaign ou étape Canvas ?

Non, cela n’est pas pris en charge actuellement.

Notifications push et activités en direct

Que se passe-t-il si une notification push est envoyée alors qu’une activité en direct est active ?

Écran de téléphone avec une activité sportive en direct Bulls vs Bears vers le milieu de l'écran et un texte de notification push lorem ipsum en bas de l'écran.

Les activités en direct et les notifications push occupent des zones d’écran différentes et n’entrent pas en conflit sur l’écran de l’utilisateur.

Si les activités en direct exploitent la fonctionnalité de notification push, les notifications push doivent-elles être activées pour recevoir les activités en direct ?

Bien que les activités en direct reposent sur les notifications push pour les mises à jour, elles sont contrôlées par des paramètres utilisateur différents. Un utilisateur peut s’abonner aux activités en direct mais pas aux notifications push, et inversement.

Les jetons de mise à jour de l’activité en direct expirent au bout de huit heures.

Les activités en direct nécessitent-elles des amorces de notification push ?

Les amorces de notification push constituent une bonne pratique pour inviter vos utilisateurs à s’abonner aux notifications push de votre application. Cependant, il n’y a pas d’invite système pour s’abonner aux activités en direct. Par défaut, les utilisateurs sont abonnés aux activités en direct pour une application individuelle lorsqu’ils installent cette application sur iOS 16.1 ou une version ultérieure. Cette autorisation peut être désactivée ou réactivée dans les paramètres de l’appareil, application par application.

Sujets techniques et résolution des problèmes

Comment savoir si les activités en direct comportent des erreurs ?

Toute erreur d’activité en direct est consignée dans le tableau de bord de Braze dans le Journal d’activité des messages, où vous pouvez filtrer par « LiveActivity Errors ».

Après avoir envoyé une notification push-to-start, pourquoi n’ai-je pas reçu mon activité en direct ?

Tout d’abord, vérifiez que votre payload comprend tous les champs obligatoires décrits dans l’endpoint messages/live_activity/start. Les champs activity_attributes et content_state doivent correspondre aux propriétés définies dans le code de votre projet. Si vous êtes certain que le payload est correct, il est possible que votre débit soit limité par les APN. Cette limite est imposée par Apple et non par Braze.

Pour vérifier que votre notification push-to-start est bien arrivée sur l’appareil mais n’a pas été affichée en raison des limites de débit, vous pouvez déboguer votre projet à l’aide de l’application Console sur votre Mac. Attachez le processus d’enregistrement pour l’appareil souhaité, puis filtrez les journaux par process:liveactivitiesd dans la barre de recherche.

Après avoir démarré mon activité en direct avec push-to-start, pourquoi ne reçoit-elle pas de nouvelles mises à jour ?

Vérifiez que vous avez correctement implémenté les instructions de l’étape 2.2 : Ajouter le protocole BrazeLiveActivityAttributes. Votre ActivityAttributes doit contenir à la fois la conformité au protocole BrazeLiveActivityAttributes et la propriété brazeActivityId.

Après avoir reçu une notification push-to-start d’activité en direct, vérifiez que vous pouvez voir une requête réseau sortante vers l’endpoint /push_token_tag de votre URL Braze et qu’elle contient le bon ID d’activité dans le champ "tag".

Enfin, assurez-vous que le type d’attribut d’activité en direct dans votre payload de mise à jour correspond exactement à la chaîne de caractères et à la classe utilisées dans votre appel de méthode SDK vers registerPushToStart. Utilisez des constantes pour éviter les erreurs de frappe.

Je reçois une réponse « Accès refusé » lorsque j’essaie d’utiliser l’endpoint live_activity/update. Pourquoi ?

Les clés API que vous utilisez doivent disposer des autorisations appropriées pour accéder aux différents endpoints de l’API Braze. Si vous utilisez une clé API que vous avez précédemment créée, il est possible que vous ayez omis de mettre à jour ses autorisations. Consultez notre aperçu de la sécurité des clés API pour en savoir plus.

L’endpoint messages/send partage-t-il les limites de débit avec l’endpoint messages/live_activity/update ?

Par défaut, la limite de débit pour l’endpoint messages/live_activity/update est de 250 000 requêtes par heure, par espace de travail et sur plusieurs endpoints. Pour plus d’informations, consultez les limites de débit de l’API.

New Stuff!