Passer au contenu principal
Les extensions de service de notification vous permettent d’intercepter et de modifier les notifications push avant qu’elles ne soient affichées à l’utilisateur. Cela permet la gestion des données en arrière-plan, les styles personnalisés, les pièces jointes de médias enrichis, la livraison confirmée et les options de boutons d’action.
Vous pouvez accéder aux données de vos notifications push envoyées depuis OneSignal via la classe OSNotification

Extension de service de notification Android

Vous permet de traiter la notification avant qu’elle ne soit affichée à l’utilisateur. Les cas d’usage courants incluent :
  • Recevoir des données en arrière-plan avec ou sans affichage de notification.
  • Remplacer des paramètres de notification spécifiques en fonction de la logique d’application côté client, comme la couleur d’accentuation personnalisée, le motif de vibration ou toute autre option NotificationCompat disponible.
Pour plus de détails, consultez la documentation d’Android sur les options NotificationCompat.

Étape 1 : Créer une classe pour l’extension de service

Créez une classe qui implémente INotificationServiceExtension et implémentez la méthode onNotificationReceived. Le paramètre de la méthode onNotificationReceived est event de type INotificationReceivedEvent.
package your.package.name

import androidx.annotation.Keep;
import com.onesignal.notifications.IActionButton;
import com.onesignal.notifications.IDisplayableMutableNotification;
import com.onesignal.notifications.INotificationReceivedEvent;
import com.onesignal.notifications.INotificationServiceExtension;

@Keep // Keep is required to prevent minification from renaming or removing your class
public class NotificationServiceExtension implements INotificationServiceExtension {

     @Override
     public void onNotificationReceived(INotificationReceivedEvent event) {
        IDisplayableMutableNotification notification = event.getNotification();

        if (notification.getActionButtons() != null) {
           for (IActionButton button : notification.getActionButtons()) {
              // you can modify your action buttons here
           }
        }

     /* Add customizations here. See examples below for additional methods to modify the notification*/
     }
}

L’annotation @Keep est nécessaire pour empêcher ProGuard ou R8 de renommer ou de supprimer votre classe lors de la minification.

Étape 2 : Personnaliser la notification

Les exemples suivants illustrent les personnalisations courantes que vous pouvez implémenter dans la classe d’extension de service de notification.
Utilisez event.preventDefault() pour supprimer l’affichage de la notification. Vous pouvez ensuite appeler event.getNotification().display() pour l’afficher plus tard, ou ne jamais l’appeler pour la rejeter silencieusement.
event.preventDefault();

//Do some async work, then decide to show or dismiss
new Thread(() -> {
    try {
        Thread.sleep(1000);
    } catch (InterruptedException ignored) {}

    //Manually show the notification
    event.getNotification().display();
}).start();
Appeler event.preventDefault() sans jamais appeler display() rejettera la notification silencieusement. Pour plus d’informations, consultez Notifications dupliquées.

Étape 3 : Ajouter l’extension de service à votre AndroidManifest.xml

Ajoutez le nom de la classe et la valeur en tant que meta-data dans le fichier AndroidManifest.xml dans la balise application. Ignorez les avertissements “unused”.
XML
<application>
  <meta-data
    android:name="com.onesignal.NotificationServiceExtension"
    android:value="com.onesignal.example.NotificationServiceExtension" />
</application>
Remplacez com.onesignal.example.NotificationServiceExtension par le nom complet de votre classe.

Extension de service de notification iOS

L’UNNotificationServiceExtension vous permet de modifier le contenu des notifications push avant qu’elles ne soient affichées à l’utilisateur et est requis pour d’autres fonctionnalités importantes comme : Vous avez probablement déjà configuré cela si vous avez suivi nos instructions de configuration du SDK mobile pour votre application, mais cette section expliquera comment accéder aux données de charge utile de notification OneSignal et résoudre les problèmes que vous pourriez rencontrer.

Obtenir la charge utile push iOS

La substitution de didReceive(_:withContentHandler:) appelle OneSignalExtension.didReceiveNotificationExtensionRequest, qui transmet le bestAttemptContent à OneSignal avant qu’il ne soit affiché à l’utilisateur. Vous pouvez lire ou modifier bestAttemptContent avant que cette méthode ne soit appelée. Dans cet exemple, nous envoyons une notification avec les données suivantes :
JSON
{
  "app_id": "YOUR_APP_ID",
  "target_channel": "push",
  "headings": {"en": "The message title"},
  "contents": {"en": "The message contents"},
  "data":{
    "additional_data_key_1":"value_1",
    "additional_data_key_2":"value_2"
    },
  "include_subscription_ids": ["SUBSCRIPTION_ID_1"]
}
Accédez à ces data supplémentaires dans la OneSignalNotificationServiceExtension via la clé a dans le dictionnaire custom de userInfo :
if let bestAttemptContent = bestAttemptContent {

    if let customData = bestAttemptContent.userInfo["custom"] as? [String: Any],
       let additionalData = customData["a"] as? [String: Any] {

        if let jsonData = try? JSONSerialization.data(withJSONObject: additionalData, options: .prettyPrinted),
           let jsonString = String(data: jsonData, encoding: .utf8) {
            print("The additionalData dictionary in JSON format:\n\(jsonString)")
        } else {
            print("Failed to convert additionalData to JSON format.")
        }
    }

    if let messageData = bestAttemptContent.userInfo["aps"] as? [String: Any],
       let apsData = messageData["alert"] as? [String: Any],
       let body = apsData["body"] as? String,
       let title = apsData["title"] as? String {
        print("The message contents is: \(body), message headings is: \(title)")
    } else {
        print("Unable to retrieve apsData")
    }

    OneSignalExtension.didReceiveNotificationExtensionRequest(self.receivedRequest,
                                                              with: bestAttemptContent,
                                                              withContentHandler: self.contentHandler)
}
Exemple de sortie console :
The additionalData dictionary in JSON format:
{
  "additional_data_key_1" : "value_1",
  "additional_data_key_2" : "value_2"
}
The message contents is: The message contents, message headings is: The message title

Dépannage de l’extension de service de notification iOS

Ce guide est destiné au débogage des problèmes avec les images, les boutons d’action ou les livraisons confirmées qui ne s’affichent pas sur les applications mobiles iOS.

Vérifiez vos paramètres Xcode

Dans General > Targets, assurez-vous que votre cible d’application principale et la cible OneSignalNotificationServiceExtension ont les mêmes paramètres corrects :
  • Supported Destinations
  • Minimum Deployment (iOS 14.5 ou supérieur)
Si vous utilisez Cocoapods, assurez-vous que ceux-ci correspondent à votre cible principale dans le Podfile pour éviter les erreurs de compilation.
Xcode General tab showing Supported Destinations and Minimum Deployment for the main app target
Xcode General tab showing Supported Destinations and Minimum Deployment for the notification service extension target
En continuant dans l’onglet OneSignalNotificationServiceExtension > Info, développez la clé NSExtension. Assurez-vous de voir :
XML
 <dict>
   <key>NSExtensionPointIdentifier</key>
   <string>com.apple.usernotifications.service</string>
   <key>NSExtensionPrincipalClass</key>
   <string>$(PRODUCT_MODULE_NAME).NotificationService</string>
 </dict>
Exemple :
Xcode Info tab showing the NSExtension dictionary with NSExtensionPointIdentifier and NSExtensionPrincipalClass keys
Si vous utilisez Objective-C, au lieu de $(PRODUCT_MODULE_NAME).NotificationService, utilisez NotificationService.

Désactiver “Copy only when installing”

Sélectionnez votre cible d’application principale > Build Phases > Embed App Extensions. Assurez-vous que “Copy only when installing” n’est PAS coché. Décochez-le s’il l’est :
Xcode Build Phases tab showing Embed App Extensions with Copy only when installing unchecked

Débogage de l’extension de service de notification iOS

Suivez ces étapes pour vérifier que l’extension de service de notification est correctement configurée.

1. Mettre à jour le code OneSignalNotificationServiceExtension

Ouvrez NotificationService.m ou NotificationService.swift et remplacez tout le contenu du fichier par le code ci-dessous. Cela ajoute des journaux pour aider à vérifier que l’extension s’exécute. Remplacez YOUR_BUNDLE_ID par votre identifiant de bundle réel.
import UserNotifications
import OneSignalExtension
import os.log

class NotificationService: UNNotificationServiceExtension {

    var contentHandler: ((UNNotificationContent) -> Void)?
    var receivedRequest: UNNotificationRequest!
    var bestAttemptContent: UNMutableNotificationContent?

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.receivedRequest = request
        self.contentHandler = contentHandler
        self.bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)

        let userInfo = request.content.userInfo
        let custom = userInfo["custom"]
        print("Running NotificationServiceExtension: userInfo = \(userInfo.description)")
        print("Running NotificationServiceExtension: custom = \(custom.debugDescription)")
        os_log("%{public}@", log: OSLog(subsystem: "YOUR_BUNDLE_ID", category: "OneSignalNotificationServiceExtension"), type: OSLogType.debug, userInfo.debugDescription)

        if let bestAttemptContent = bestAttemptContent {
            print("Running NotificationServiceExtension")
            bestAttemptContent.body = "[Modified] " + bestAttemptContent.body

            OneSignalExtension.didReceiveNotificationExtensionRequest(self.receivedRequest, with: bestAttemptContent, withContentHandler: self.contentHandler)
        }
    }

    override func serviceExtensionTimeWillExpire() {
        if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
            OneSignalExtension.serviceExtensionTimeWillExpireRequest(self.receivedRequest, with: self.bestAttemptContent)
            contentHandler(bestAttemptContent)
        }
    }

}

Les types de journaux de débogage doivent être activés dans la Console via Action > Include Debug Messages.

2. Changer votre schéma actif

Définissez votre schéma actif sur OneSignalNotificationServiceExtension.
Xcode toolbar showing the active scheme dropdown set to OneSignalNotificationServiceExtension

3. Compiler et exécuter le projet

Compilez et exécutez le projet dans Xcode sur un appareil réel.

4. Ouvrir la console

Dans Xcode, sélectionnez Window > Devices and Simulators.
Xcode menu showing the Window dropdown with Devices and Simulators selected
Vous devriez voir votre appareil connecté. Sélectionnez Open Console.
Xcode Devices window showing the Open Console button for a connected device

5. Vérifier la console

Dans la console :
  1. Sélectionnez Action > Include Debug Messages
  2. Recherchez OneSignalNotificationServiceExtension comme CATEGORY
  3. Sélectionnez Start
macOS Console app showing the category filter and Start button for debugging the notification service extension
Envoyez une notification avec un message à cet appareil (utilisez la propriété contents si vous envoyez depuis l’API Créer une notification). Dans cet exemple, la charge utile est :
cURL
curl --request POST \
 --url 'https://api.onesignal.com/notifications' \
 --header 'Authorization: Key YOUR_API_KEY' \
 --header 'accept: application/json' \
 --header 'content-type: application/json' \
 --data '
{
"app_id": "YOUR_APP_ID",
"target_channel": "push",
"headings": {"en": "The message title"},
"contents": {"en": "The message contents"},
"data":{"additional_data_key_1":"value_1","additional_data_key_2":"value_2"},
"include_subscription_ids": [
"SUBSCRIPTION_ID_1"
]
}'
Vous devriez voir un message enregistré avec l’application en cours d’exécution et non en cours d’exécution.
macOS Console app showing debug log output from the OneSignalNotificationServiceExtension
Si vous ne voyez pas de message, supprimez OneSignal de votre application et suivez à nouveau la Configuration du SDK mobile pour vérifier l’intégration.

FAQ

Pourquoi mon extension de service de notification ne s’exécute-t-elle pas sur iOS ? L’extension ne s’exécute que lorsque mutable-content est défini dans la charge utile de la notification. OneSignal le définit automatiquement pour les notifications avec des pièces jointes ou des boutons d’action. Vérifiez que vos paramètres Xcode correspondent à la section de dépannage. Puis-je empêcher l’affichage d’une notification sur Android ? Oui. Appelez event.preventDefault() pour supprimer l’affichage. Appelez ensuite event.getNotification().display() pour l’afficher plus tard, ou ne l’appelez jamais pour la rejeter silencieusement. Consultez Notifications dupliquées pour plus d’informations. Ai-je besoin de l’annotation @Keep sur Android ? Oui. Elle empêche ProGuard ou R8 de renommer ou de supprimer votre classe implémentant INotificationServiceExtension lors de la minification.

Pages associées

Configuration du SDK mobile

Installez et configurez le SDK OneSignal pour iOS et Android.

Images et médias enrichis

Joignez des images, des GIFs et des vidéos aux notifications push.

Livraison confirmée

Suivez la livraison confirmée des notifications aux appareils.

Notifications dupliquées

Résolvez les notifications push dupliquées sur toutes les plateformes.