Notification Extension est un mécanisme iOS qui permet de modifier le contenu et l'apparence des notifications push avant leur affichage à l'utilisateur. Les extensions fonctionnent côté système d'exploitation dans un processus séparé : UNNotificationServiceExtension traite le contenu entrant, tandis que UNNotificationContentExtension gère l'interface. Selon Apple Developer Documentation, 2026, la Service Extension dispose de 30 secondes maximum pour effectuer des tâches avant l'affichage de la notification. Cette limitation est critique lors du téléchargement de pièces jointes ou du déchiffrement de données.
Points clés
Notification Extension est un composant logiciel iOS qui étend le comportement standard des notifications push en ajoutant la possibilité de modifier le contenu et de personnaliser l'interface. Contrairement aux notifications ordinaires qui sont affichées par le système dans un format standard, les extensions permettent au développeur d'influencer le contenu avant l'affichage et de créer une interface utilisateur unique.
Apple fournit deux types de Notification Extension à des fins différentes : UNNotificationServiceExtension gère le traitement du payload entrant, tandis que UNNotificationContentExtension gère l'affichage. Service Extension s'exécute avant que la notification ne soit affichée et dispose d'un temps d'exécution limité — jusqu'à 30 secondes selon Apple Developer Documentation. Content Extension s'active après que l'utilisateur a interagi avec la notification et affiche une vue personnalisée.
Une notification push iOS standard est affichée automatiquement par le système en fonction des champs alert, title et subtitle du payload JSON. Notification Extension intercepte le contrôle : Service Extension reçoit le payload brut, le modifie et le transmet au système pour affichage. Content Extension remplace la bannière standard par une interface personnalisée avec tous les éléments de contrôle souhaités.
Lorsque l'appareil reçoit une notification push avec la clé mutable-content: 1, le système lance Service Extension dans un processus séparé. Le processus de l'extension est isolé de l'application principale et possède son propre sandbox avec une limite mémoire de 50 Mo. Après avoir terminé le traitement, l'extension appelle le completion handler, transmettant le UNNotificationContent modifié au système pour affichage.
UNNotificationServiceExtension est l'outil principal pour modifier programmatiquement les notifications push avant qu'elles ne soient affichées à l'utilisateur. L'extension s'active automatiquement à la réception d'une notification dont le payload a le flag mutable-content: 1 activé. En 30 secondes, l'extension peut télécharger une pièce jointe multimédia, modifier le texte, déchiffrer des données cryptées ou enrichir le contenu.
L'extension implémente deux méthodes clés du protocole UNNotificationServiceExtension. La méthode didReceive reçoit la requête entrante avec le UNNotificationRequest brut et permet la modification via le completion handler avec un nouveau UNNotificationContent. La méthode serviceExtensionTimeWillExpire est appelée par le système une seconde avant le timeout — dans celle-ci, vous devez terminer le traitement et passer le résultat actuel (éventuellement partiel).
Considérons un scénario où le serveur envoie un push avec une URL d'image dans un champ personnalisé. Service Extension télécharge cette image sur le réseau, crée un UNNotificationAttachment et l'ajoute au contenu. UNNotificationAttachment accepte un fichier local d'image, de vidéo ou d'audio et le copie automatiquement dans le sandbox de l'extension. Après avoir créé la pièce jointe, l'extension transmet le contenu mis à jour au système.
class NotificationService: UNNotificationServiceExtension {
override func didReceive(_ request: UNNotificationRequest,
withContentHandler contentHandler:
@escaping (UNNotificationContent) -> Void) {
let userInfo = request.content.userInfo
guard let imageURL = URL(string: userInfo["image-url"] as! String)
else { contentHandler(request.content); return }
let attachment = try! UNNotificationAttachment(
identifier: "image", url: imageURL,
options: [UNNotificationAttachmentOptionsTypeHintKey: "jpg"])
let modifiedContent = request.content.mutableCopy()
as! UNMutableNotificationContent
modifiedContent.attachments = [attachment]
contentHandler(modifiedContent)
}
override func serviceExtensionTimeWillExpire() {
contentHandler?(bestAttemptContent ?? request.content)
}
}
Lorsque des notifications avec les mêmes pièces jointes sont envoyées fréquemment, il est recommandé de mettre en cache les fichiers téléchargés sur l'appareil. FileManager fournit un accès au répertoire de cache de l'extension, qui persiste entre les lancements. Cela réduit le temps de traitement des notifications suivantes et diminue la charge réseau. Selon Apple, la mise en cache peut réduire le temps de traitement à 2–5 secondes au lieu d'un téléchargement complet.
UNNotificationContentExtension permet de remplacer la bannière de notification standard par une interface personnalisée créée dans Interface Builder ou SwiftUI. L'extension s'active lorsque l'utilisateur effectue une action sur la notification : tap, balayage vers le bas ou 3D Touch. Content Extension reçoit le contenu déjà traité par Service Extension et l'affiche dans une vue personnalisée.
Chaque Content Extension est liée à une ou plusieurs catégories de notification via Info.plist. La catégorie est définie sur le serveur par le champ category dans le payload APNS. Le système sélectionne automatiquement l'extension appropriée en fonction de la catégorie de la notification reçue. L'interface est construite via storyboard en utilisant des composants UIKit standard ou SwiftUI View.
Content Extension prend en charge les boutons personnalisés et les gestionnaires de tap définis dans UNNotificationAction. UNNotificationAction est créé à l'étape d'enregistrement de la catégorie et peut prendre en charge la saisie de texte via UNTextInputNotificationAction. Lorsque l'utilisateur appuie sur un bouton, l'extension reçoit le callback didReceive avec l'identifiant de l'action et peut exécuter la logique correspondante — ouvrir une URL, envoyer une requête au serveur ou mettre à jour l'interface.
Content Extension s'exécute dans un processus isolé avec sa propre boucle d'exécution et une limite mémoire d'environ 50 Mo. Les performances de l'extension sont critiques car le watchdog du système termine le processus lorsque les limites sont dépassées. Il est recommandé d'éviter les calculs lourds, le chargement de grandes images et les requêtes réseau longues à l'intérieur de Content Extension.
UNNotificationAttachment est un objet qui ajoute un fichier multimédia à une notification push : image, vidéo, audio ou GIF. La pièce jointe est créée à partir d'une URL de fichier local qui doit se trouver dans le sandbox de l'extension. La taille maximale de la pièce jointe ne doit pas dépasser 10 Mo, sinon le système rejettera la pièce jointe lors de sa création.
Apple prend en charge un ensemble limité de formats pour les pièces jointes multimédia. Images — JPEG, PNG, GIF (y compris animés), TIFF. Vidéo — MPEG, MP4, MOV avec une durée maximale de 30 secondes. Audio — MP3, AAC, WAV, CAF. Pour chaque format, vous pouvez spécifier le type via UNNotificationAttachmentOptionsTypeHintKey, ce qui aide le système à traiter le fichier correctement.
Étant donné que le payload push contient uniquement une URL, pas le fichier lui-même, le téléchargement de la pièce jointe doit être effectué à l'intérieur de Service Extension. Le temps de téléchargement maximum est limité à 30 secondes, il est donc recommandé d'utiliser URLSession avec des paramètres minimaux et de désactiver le téléchargement en cas de signal faible. Si la pièce jointe ne se charge pas à temps, la notification s'affiche sans multimédia — c'est le comportement par défaut du système.
Parcourons un exemple complet de Notification Extension qui télécharge une image, la sauvegarde et l'ajoute à la notification. NotificationService hérite de UNNotificationServiceExtension et remplace la méthode didReceive. L'exemple montre la gestion des champs optionnels, la création de la pièce jointe et l'appel du completion handler avec le contenu modifié.
import UserNotifications
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(
_ request: UNNotificationRequest,
withContentHandler contentHandler:
@escaping (UNNotificationContent) -> Void
) {
self.contentHandler = contentHandler
self.bestAttemptContent =
(request.content.mutableCopy()
as! UNMutableNotificationContent)
guard let attachmentURLString =
bestAttemptContent?.userInfo["attachment-url"] as? String,
let url = URL(string: attachmentURLString)
else {
contentHandler(request.content)
return
}
URLSession.shared.downloadTask(with: url) {
[weak self] localURL, _, error in
guard let localURL = localURL, error == nil
else {
contentHandler(request.content)
return
}
let attachment = try! UNNotificationAttachment(
identifier: "media", url: localURL)
self?.bestAttemptContent?.attachments = [attachment]
contentHandler(self?.bestAttemptContent
?? request.content)
}.resume()
}
override func serviceExtensionTimeWillExpire() {
if let content = bestAttemptContent {
contentHandler?(content)
}
}
}
Pour que l'extension fonctionne correctement, il est nécessaire d'enregistrer les catégories de notification dans Info.plist. La clé NSExtensionPointIdentifier est définie sur com.apple.usernotifications.service pour Service Extension ou com.apple.usernotifications.content pour Content Extension. Les catégories sont définies dans AppDelegate au lancement de l'application via UNUserNotificationCenter, et l'extension ne s'active que pour les notifications avec une catégorie correspondante dans le payload.
Foire aux questions
Service Extension modifie le contenu avant l'affichage de la notification — ajoute des médias, change le texte, déchiffre les données. Content Extension remplace l'interface de la notification par une interface personnalisée après l'interaction de l'utilisateur. Service Extension fonctionne avant l'affichage, Content Extension après.
Le système alloue 30 secondes pour l'exécution du code dans didReceive. Si le traitement n'est pas terminé dans ce délai, serviceExtensionTimeWillExpire est appelé, où vous devez passer le résultat actuel. Il est recommandé de rester dans les 10–15 secondes en tenant compte des téléchargements de pièces jointes.
Oui, SwiftUI est pris en charge dans Content Extension à partir d'iOS 16. La View est encapsulée dans un UIHostingController et ajoutée au storyboard. Cependant, en raison des limites de mémoire, il est recommandé d'utiliser SwiftUI uniquement pour des interfaces simples avec un nombre minimal d'éléments.
En cas d'erreur de téléchargement ou de dépassement du délai, appelez simplement le completion handler avec le contenu original sans pièce jointe. Le système affichera la notification sous forme standard sans multimédia. Enregistrez les erreurs via OSLog pour le diagnostic, mais ne bloquez pas l'affichage de la notification.
L'extension s'exécute dans un processus isolé avec une limite d'environ 50 Mo. En cas de dépassement, le système tue le processus via le watchdog. Évitez de charger de gros fichiers, de stocker des images en mémoire et les fuites lors du travail avec URLSession.
Résumé
Nous développerons une application mobile clé en main
IT Sectr crée des applications iOS et Android pour les startups et les entreprises depuis 2017. Nous vous conseillerons et vous proposerons la meilleure solution.
Lisez aussi