Notification Extension: kluczowe pojęcia, typy rozszerzeń i konfiguracja

Autor: IT Sectr Opublikowano: 2026-03-20 Czas czytania: 8 min

Notification Extension to mechanizm iOS, który umożliwia modyfikację treści i wyglądu powiadomień push przed ich wyświetleniem użytkownikowi. Rozszerzenia działają po stronie systemu operacyjnego w oddzielnym procesie: UNNotificationServiceExtension przetwarza przychodzącą treść, a UNNotificationContentExtension zarządza interfejsem. Według Apple Developer Documentation, 2026, Service Extension ma do 30 sekund na wykonanie zadań przed wyświetleniem powiadomienia. To ograniczenie jest krytyczne przy pobieraniu załączników lub deszyfrowaniu danych.

Najważniejsze

  • Service Extension — przechwytuje powiadomienie przed wyświetleniem, umożliwia zmianę tekstu, dodawanie multimediów i deszyfrowanie danych z limitem 30 sekund.
  • Content Extension — tworzy niestandardowy interfejs powiadomienia z dowolnym UI, przyciskami i obsługą dotknięć przez storyboard lub SwiftUI.
  • Załączniki multimedialne — obrazy, wideo i audio dodawane są przez UNNotificationAttachment w Service Extension przed przekazaniem do Content Extension.
  • Rejestracja — oba rozszerzenia rejestruje się w Info.plist jako osobne targety z określeniem kategorii powiadomień i NSExtensionPointIdentifier.
  • Ograniczenia — rozszerzenia nie mają dostępu do głównej aplikacji, działają w izolowanej piaskownicy z limitem pamięci 50 MB.

Czym jest Notification Extension

Notification Extension to komponent programowy iOS, który rozszerza standardowe zachowanie powiadomień push, dodając możliwość modyfikacji treści i personalizacji interfejsu. W przeciwieństwie do zwykłych powiadomień, które są wyświetlane przez system w standardowej formie, rozszerzenia pozwalają programiście wpływać na treść przed wyświetleniem i tworzyć unikalny interfejs użytkownika.

Dwa typy rozszerzeń powiadomień

Apple udostępnia dwa typy Notification Extension do różnych celów: UNNotificationServiceExtension odpowiada za przetwarzanie przychodzącego payloadu, a UNNotificationContentExtension zarządza wyświetlaniem. Service Extension uruchamia się przed wyświetleniem powiadomienia i ma ograniczony czas na wykonanie — do 30 sekund według Apple Developer Documentation. Content Extension aktywuje się po interakcji użytkownika z powiadomieniem i wyświetla niestandardowy widok.

Różnica w stosunku do standardowych powiadomień

Standardowe powiadomienie push iOS jest wyświetlane przez system automatycznie na podstawie pól alert, title i subtitle z JSON-payloadu. Notification Extension przechwytuje sterowanie: Service Extension otrzymuje surowy payload, modyfikuje go i przekazuje systemowi do wyświetlenia. Content Extension zastępuje standardowy baner dowolnym interfejsem z dowolnymi elementami sterowania.

Cykl życia rozszerzenia

Gdy urządzenie otrzyma push z kluczem mutable-content: 1, system uruchamia Service Extension w oddzielnym procesie. Proces rozszerzenia jest izolowany od głównej aplikacji i ma własną piaskownicę z limitem pamięci 50 MB. Po zakończeniu przetwarzania rozszerzenie wywołuje completion handler, przekazując zmodyfikowany UNNotificationContent systemowi do wyświetlenia.

UNNotificationServiceExtension: modyfikacja treści

UNNotificationServiceExtension to podstawowe narzędzie do programowej zmiany powiadomień push przed ich wyświetleniem użytkownikowi. Rozszerzenie aktywuje się automatycznie po otrzymaniu powiadomienia, w którego payloadzie ustawiono flagę mutable-content: 1. W ciągu 30 sekund rozszerzenie może pobrać załącznik multimedialny, zmienić tekst, odszyfrować zaszyfrowane dane lub wzbogacić treść.

Metody protokołu UNNotificationServiceExtension

Rozszerzenie implementuje dwie kluczowe metody z protokołu UNNotificationServiceExtension. Metoda didReceive otrzymuje przychodzące żądanie z surowym UNNotificationRequest i umożliwia jego modyfikację przez completion handler z nowym UNNotificationContent. Metoda serviceExtensionTimeWillExpire jest wywoływana przez system na sekundę przed upływem limitu czasu — w niej należy zakończyć przetwarzanie i przekazać bieżący (ewentualnie częściowy) wynik.

Przykład: dodawanie obrazu do powiadomienia

Rozważmy scenariusz, w którym serwer wysyła push z URL-em obrazu w niestandardowym polu. Service Extension pobiera ten obraz przez sieć, tworzy UNNotificationAttachment i dodaje go do treści. UNNotificationAttachment przyjmuje lokalny plik obrazu, wideo lub audio i automatycznie kopiuje go do sandboxa rozszerzenia. Po utworzeniu attachment rozszerzenie przekazuje zaktualizowaną treść systemowi.

swift
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)
    }
}

Buforowanie i ponowne wykorzystanie

Przy częstym wysyłaniu powiadomień z tymi samymi załącznikami zaleca się buforowanie pobranych plików na urządzeniu. FileManager udostępnia dostęp do katalogu pamięci podręcznej rozszerzenia, który jest zachowywany między uruchomieniami. Skraca to czas przetwarzania kolejnych powiadomień i zmniejsza obciążenie sieci. Według Apple buforowanie załączników może skrócić czas przetwarzania do 2–5 sekund zamiast pełnego pobierania.

UNNotificationContentExtension: niestandardowy interfejs

UNNotificationContentExtension pozwala zastąpić standardowy baner powiadomienia dowolnym interfejsem utworzonym w Interface Builder lub SwiftUI. Rozszerzenie aktywuje się, gdy użytkownik wykona akcję z powiadomieniem: dotknięcie, przesunięcie w dół lub 3D Touch. Content Extension otrzymuje treść już przetworzoną przez Service Extension i wyświetla ją w niestandardowym widoku.

Storyboard i kategorie powiadomień

Każdy Content Extension jest powiązany z jedną lub kilkoma kategoriami powiadomień przez Info.plist. Kategoria jest określana na serwerze polem category w payloadzie APNS. System automatycznie wybiera odpowiednie rozszerzenie na podstawie kategorii otrzymanego powiadomienia. Interfejs buduje się przez storyboard z użyciem standardowych komponentów UIKit lub SwiftUI View.

Obsługa działań użytkownika

Content Extension obsługuje niestandardowe przyciski i procedury obsługi dotknięć zdefiniowane w UNNotificationAction. UNNotificationAction jest tworzony na etapie rejestracji kategorii i może być wprowadzaniem tekstu przez UNTextInputNotificationAction. Gdy użytkownik naciśnie przycisk, rozszerzenie otrzymuje callback didReceive z identyfikatorem działania i może wykonać odpowiednią logikę — otworzyć URL, wysłać żądanie do serwera lub zaktualizować interfejs.

Ograniczenia wydajności

Content Extension działa w izolowanym procesie z własną pętlą wykonawczą i limitem pamięci około 50 MB. Wydajność rozszerzenia jest krytyczna, ponieważ systemowy watchdog kończy proces po przekroczeniu limitów. Zaleca się unikanie ciężkich obliczeń, pobierania dużych obrazów i długotrwałych żądań sieciowych wewnątrz Content Extension.

Załączniki multimedialne i UNNotificationAttachment

UNNotificationAttachment to obiekt, który dodaje plik multimedialny do powiadomienia push: obraz, wideo, audio lub GIF. Załącznik jest tworzony z lokalnego URL pliku, który musi znajdować się w piaskownicy rozszerzenia. Maksymalny rozmiar załącznika nie może przekraczać 10 MB, w przeciwnym razie system odrzuci attachment podczas tworzenia.

Obsługiwane formaty

Apple obsługuje ograniczony zestaw formatów załączników multimedialnych. Obrazy — JPEG, PNG, GIF (w tym animowane), TIFF. Wideo — MPEG, MP4, MOV z maksymalnym czasem trwania 30 sekund. Audio — MP3, AAC, WAV, CAF. Dla każdego formatu można określić typ przez UNNotificationAttachmentOptionsTypeHintKey, co pomaga systemowi poprawnie przetworzyć plik.

Pobieranie załącznika z sieci

Ponieważ payload push zawiera tylko URL, a nie sam plik, pobieranie załącznika musi odbywać się wewnątrz Service Extension. Maksymalny czas pobierania jest ograniczony do 30 sekund, dlatego zaleca się używanie URLSession z minimalnymi ustawieniami i wyłączanie pobierania przy słabym sygnale. Jeśli załącznik nie został pobrany na czas, powiadomienie jest wyświetlane bez multimediów — to domyślne zachowanie systemu.

Przykład implementacji w Swift

Rozważmy pełny przykład Notification Extension, który pobiera obraz, ściąga go i dodaje do powiadomienia. NotificationService dziedziczy po UNNotificationServiceExtension i nadpisuje metodę didReceive. W przykładzie pokazano obsługę opcjonalnych pól, tworzenie attachment i wywołanie completion handlera ze zmodyfikowaną treścią.

swift
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)
        }
    }
}

Konfiguracja Info.plist dla rozszerzenia

Do poprawnego działania rozszerzenia należy zarejestrować kategorie powiadomień w Info.plist. Klucz NSExtensionPointIdentifier ustawia się na com.apple.usernotifications.service dla Service Extension lub com.apple.usernotifications.content dla Content Extension. Kategorie są określane w AppDelegate podczas uruchamiania aplikacji przez UNUserNotificationCenter, a rozszerzenie aktywuje się tylko dla powiadomień z odpowiednią kategorią w payloadzie.

Często zadawane pytania

Czym różni się Service Extension od Content Extension?

Service Extension modyfikuje treść przed wyświetleniem powiadomienia — dodaje multimedia, zmienia tekst, deszyfruje dane. Content Extension zastępuje interfejs powiadomienia niestandardowym po interakcji użytkownika. Service Extension działa przed wyświetleniem, Content Extension — po.

Ile czasu jest na przetwarzanie w Service Extension?

System przydziela 30 sekund na wykonanie kodu w didReceive. Jeśli przetwarzanie nie zakończy się w tym czasie, wywoływana jest metoda serviceExtensionTimeWillExpire, w której należy przekazać bieżący wynik. Zaleca się zmieścić w 10–15 sekund, uwzględniając pobieranie załączników.

Czy można używać SwiftUI w Content Extension?

Tak, SwiftUI jest obsługiwane w Content Extension od iOS 16. View owija się w UIHostingController i dodaje do storyboard. Jednak ze względu na limity pamięci zaleca się używanie SwiftUI tylko dla prostych interfejsów z minimalną liczbą elementów.

Jak obsługiwać błędy pobierania załączników?

W przypadku błędu pobierania lub przekroczenia limitu czasu wystarczy wywołać completion handler z oryginalną treścią bez attachment. System wyświetli powiadomienie w standardowej formie bez multimediów. Rejestruj błędy przez OSLog do diagnostyki, ale nie blokuj wyświetlania powiadomienia.

Jakie są ograniczenia pamięci Notification Extension?

Rozszerzenie działa w izolowanym procesie z limitem około 50 MB. Po przekroczeniu limitu system zabija proces przez watchdog. Unikaj pobierania dużych plików, przechowywania obrazów w pamięci i wycieków podczas pracy z URLSession.

Podsumowanie

  • Notification Extension — mechanizm iOS do modyfikacji powiadomień push, obejmujący Service Extension (treść) i Content Extension (interfejs).
  • Service Extension przetwarza payload przed wyświetleniem powiadomienia z limitem 30 sekund, może dodawać załączniki multimedialne i deszyfrować dane.
  • Content Extension zastępuje standardowy baner niestandardowym interfejsem przez UIKit lub SwiftUI z obsługą interaktywnych przycisków.
  • UNNotificationAttachment dodaje obrazy, wideo i audio do powiadomienia, obsługując formaty JPEG, PNG, MP4, MP3 i inne.
  • Rejestracja rozszerzeń odbywa się przez Info.plist z określeniem NSExtensionPointIdentifier i kategorii powiadomień do aktywacji.
  • Ograniczenia — limit pamięci 50 MB, izolowana piaskownica bez dostępu do głównej aplikacji, ograniczony czas wykonania.
  • Notification Extension to kluczowe narzędzie do tworzenia bogatych powiadomień użytkownika, zwiększające zaangażowanie i funkcjonalność komunikacji push w iOS.

Opracujemy aplikację mobilną pod klucz

IT Sectr tworzy aplikacje na iOS i Androida dla startupów i firm od 2017 roku. Doradzimy Ci i zaproponujemy najlepsze rozwiązanie.

Omów projekt

Przeczytaj również