Notification Service Extension — adalah ekstensi iOS yang mencegat notifikasi push sebelum ditampilkan kepada pengguna dan memungkinkan modifikasi konten. Ekstensi dapat mendekripsi data terenkripsi, mengunduh lampiran media, mengubah teks, atau menambahkan bidang kustom. Menurut Apple Developer, 2025, Notification Service Extension memiliki hingga 30 detik untuk menjalankan tugas di latar belakang.
Utama
Notification Service Extension — adalah ekstensi aplikasi di iOS yang dijalankan sebelum notifikasi push ditampilkan. Memungkinkan server mengirim payload minimal, dan ekstensi melengkapinya dengan konten: mengunduh gambar, mendekripsi data, mengganti teks. Pengguna melihat notifikasi yang sudah siap dan diproses.
Ketika iOS menerima notifikasi push, sistem memeriksa keberadaan ekstensi untuk aplikasi tersebut. Jika ekstensi terdaftar, iOS menjalankannya di proses latar belakang dan mengirimkan konten notifikasi melalui metode didReceive(_:withContentHandler:). Ekstensi memproses konten dan memanggil contentHandler dengan konten yang dimodifikasi. Jika ekstensi tidak selesai dalam 30 detik, sistem menampilkan notifikasi asli.
Service Extension diperlukan dalam skenario di mana konten notifikasi memerlukan pemrosesan di perangkat. Komunikasi aman: server mengirim payload terenkripsi, ekstensi mendekripsinya secara lokal. Notifikasi media kaya: server mengirim URL gambar, ekstensi mengunduh dan melampirkannya. Lokalisasi dinamis: ekstensi mengganti teks dalam bahasa perangkat.
| Skenario | Tanpa ekstensi | Dengan ekstensi |
|---|---|---|
| Gambar | Tidak didukung | Diunduh dan ditampilkan |
| Enkripsi | Server menyimpan kunci | Dekripsi di perangkat |
| Teks | Ditetapkan di server | Penggantian dinamis |
| Validasi | Tidak diperiksa | Pembatalan notifikasi berbahaya |
Notification Service Extension bekerja di lingkungan terbatas. Waktu eksekusi maksimum — 30 detik. Ekstensi tidak memiliki akses ke penyimpanan utama aplikasi (kecuali App Group). Ukuran ekstensi dibatasi 50 MB. Saat waktu habis, sistem memanggil contentHandler dengan konten asli dan semua perubahan hilang.
Di Xcode, Notification Service Extension ditambahkan dengan membuat target baru tipe Notification Service Extension. Xcode menghasilkan template kelas NotificationService yang mewarisi UNNotificationServiceExtension, dengan dua metode: didReceive dan serviceExtensionTimeWillExpire.
Di Xcode pilih File → New → Target → Notification Service Extension. Tentukan nama (misalnya PushNotificationService) dan bahasa Swift. Pastikan target ditambahkan ke aplikasi utama dan memiliki tanda tangan yang benar. Setelah dibuat, kelas NotificationService.swift akan dihasilkan dengan implementasi dasar.
Info.plist ekstensi berisi kunci NSExtension dengan subkunci NSExtensionPointIdentifier (com.apple.usernotifications.service) dan NSExtensionPrincipalClass (nama controller Anda). Secara opsional dapat ditentukan NSExtensionAttributes dengan aturan aktivasi ekstensi. Pengaturan ini dihasilkan secara otomatis oleh Xcode.
Implementasi dasar menimpa didReceive, memodifikasi konten notifikasi, dan memanggil contentHandler. Jika pemrosesan terlalu lama, serviceExtensionTimeWillExpire dipanggil, di mana Anda harus menyelesaikan pekerjaan dengan status saat ini.
import UserNotifications
class NotificationService: UNNotificationServiceExtension {
var contentHandler: ((UNNotificationContent) -> Void)?
var bestAttemptContent: UNMutableNotificationContent?
override func didReceive(
request: UNNotificationRequest,
withContentHandler handler: @escaping (UNNotificationContent) -> Void
) {
contentHandler = handler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
if let bestAttemptContent = bestAttemptContent {
bestAttemptContent.title = "[Diproses] \(bestAttemptContent.title)"
contentHandler?(bestAttemptContent)
}
}
override func serviceExtensionTimeWillExpire() {
if let contentHandler = contentHandler,
let bestAttemptContent = bestAttemptContent {
contentHandler(bestAttemptContent)
}
}
}
Salah satu aplikasi utama Service Extension adalah dekripsi konten notifikasi di perangkat. Server mengirim payload terenkripsi, dan ekstensi mendekripsinya menggunakan kunci yang disimpan di Keychain atau App Group. Ini memastikan konten tidak dapat dicegat selama transmisi.
Server mengenkripsi body notifikasi menggunakan kunci simetris (AES-256). Kunci enkripsi disepakati sebelumnya antara klien dan server. Ekstensi menerima string terenkripsi di bidang data payload, mendekripsinya, dan menempatkannya di bidang notifikasi. Kunci pengguna dapat diperoleh dari Keychain setelah autentikasi.
override func didReceive(
request: UNNotificationRequest,
withContentHandler handler: @escaping (UNNotificationContent) -> Void
) {
guard let content = request.content.mutableCopy()
as? UNMutableNotificationContent else {
handler(request.content)
return
}
guard let encryptedData = content.userInfo["encrypted_data"]
as? String else {
handler(content)
return
}
let decrypted = CryptoService.decrypt(encryptedData)
content.body = decrypted.body
content.title = decrypted.title
handler(content)
}
Kunci dekripsi tidak boleh disimpan di kode ekstensi atau NSUserDefaults. Gunakan iOS Keychain dengan akses melalui App Group agar baik aplikasi maupun ekstensi dapat membaca kunci. Untuk menghasilkan kunci di sisi klien, gunakan Security.framework dengan algoritma AES-256-GCM.
Penggunaan paling umum dari Notification Service Extension — mengunduh gambar, GIF, dan video untuk ditampilkan di notifikasi. Server mengirim URL file media, dan ekstensi mengunduhnya, menyimpannya ke direktori sementara, dan membuat UNNotificationAttachment.
Ekstensi menerima URL gambar dari bidang payload notifikasi. Menggunakan URLSession, ekstensi mengunduh file ke direktori sementara. Setelah unduhan selesai, UNNotificationAttachment dibuat dengan URL lokal. Lampiran diteruskan ke konten yang dimodifikasi. iOS secara otomatis menampilkan gambar di antarmuka standar atau di Notification Content Extension.
private func downloadAndAttachMedia(
content: UNMutableNotificationContent,
mediaUrl: String,
handler: @escaping (UNNotificationContent) -> Void
) {
guard let url = URL(string: mediaUrl) else {
handler(content)
return
}
let task = URLSession.shared.downloadTask(with: url) { localUrl, _, error in
guard let localUrl = localUrl, error == nil else {
handler(content)
return
}
let attachment = try? UNNotificationAttachment(
identifier: "media",
url: localUrl,
options: nil
)
if let attachment = attachment {
content.attachments = [attachment]
}
handler(content)
}
task.resume()
}
iOS mendukung format berikut untuk ditampilkan di notifikasi: JPEG, PNG, GIF (statis), video MPEG-4 hingga 50 MB. Untuk file audio, MP3, AAC, dan ALAC didukung. Penting: semua file media harus diunduh dalam batas 30 detik. Untuk file besar, pemotongan sisi server atau unduhan progresif direkomendasikan.
Manajemen batas 30 detik — tugas utama dalam mengembangkan Notification Service Extension. Jika ekstensi tidak menyelesaikan pemrosesan, sistem memanggil serviceExtensionTimeWillExpire dan menampilkan konten asli. Skenario fallback harus disediakan untuk setiap jenis pemrosesan.
Bagi tugas berdasarkan prioritas. Modifikasi kritis (dekripsi, lokalisasi dasar) lakukan terlebih dahulu. Peningkatan opsional (unduh gambar, pengayaan teks) — di urutan kedua. Gunakan URLSession dengan timeout untuk permintaan jaringan agar tidak menghabiskan seluruh batas pada satu operasi.
Jika unduhan gambar gagal atau dekripsi payload mengembalikan error, ekstensi harus memanggil contentHandler dengan konten asli. Jangan pernah mengakhiri ekstensi tanpa memanggil contentHandler — ini menyebabkan hilangnya notifikasi. Fallback aman harus selalu disediakan dalam kode ekstensi.
override func didReceive(
request: UNNotificationRequest,
withContentHandler handler: @escaping (UNNotificationContent) -> Void
) {
let content = (request.content.mutableCopy()
as? UNMutableNotificationContent) ?? request.content
// Tugas kritis: dekripsi
var decryptedContent = tryDecryptPayload(content)
// Tugas opsional: media
guard let mediaUrl = decryptedContent.userInfo["media_url"]
as? String else {
handler(decryptedContent)
return
}
downloadAndAttachMedia(
content: decryptedContent,
mediaUrl: mediaUrl,
handler: handler
)
}
Untuk menguji Notification Service Extension gunakan Xcode: pilih target ekstensi, jalankan di simulator, dan kirim notifikasi push melalui terminal atau Firebase Console. Log setiap tahap pemrosesan melalui os_log — ini membantu mendiagnosis masalah waktu dan kesalahan muat.
Pertanyaan Umum
Sistem akan memanggil serviceExtensionTimeWillExpire, lalu menampilkan notifikasi asli tanpa perubahan. Semua file yang diunduh dan modifikasi akan dibuang.
Ya, jika Anda memanggil contentHandler dengan konten kosong (UNNotificationContent dengan bidang kosong), notifikasi tidak akan ditampilkan. Ini digunakan untuk memfilter notifikasi spam atau data yang salah.
Token dapat diteruskan di userInfo payload notifikasi atau diperoleh dari Keychain melalui App Group. Menyimpan token di UserDefaults ekstensi tidak disarankan.
Ekstensi harus ditandatangani dengan sertifikat pengembang yang sama dengan aplikasi utama. Untuk produksi diperlukan sertifikat produksi dengan capability Push Notifications diaktifkan.
Hubungkan perangkat ke Xcode, pilih target ekstensi di skema peluncuran, dan kirim notifikasi push melalui Firebase Console. Breakpoints di ekstensi berfungsi sama seperti di aplikasi utama.
Ringkasan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga