Notification Service Extension, kullanıcıya gösterilmeden önce bir push bildirimini yakalayan ve içeriği değiştirmeye izin veren bir iOS uzantısıdır. Uzantı, şifrelenmiş verilerin şifresini çözebilir, medya eklerini indirebilir, metni değiştirebilir veya özel alanlar ekleyebilir. Apple Developer, 2025'e göre, Notification Service Extension görevi arka planda tamamlamak için 30 saniyeye kadar süreye sahiptir.
Önemli Noktalar
Notification Service Extension, bir push bildirimi görüntülenmeden önce çalışan bir iOS uygulama uzantısıdır. Sunucunun minimum payload göndermesine izin verirken, uzantı bunu içerikle zenginleştirir: resim indirme, veri şifre çözme, metin değiştirme. Kullanıcı zaten işlenmiş bildirimi görür.
iOS bir push bildirimi aldığında, sistem uygulama için bir uzantı olup olmadığını kontrol eder. Uzantı kayıtlıysa, iOS onu bir arka plan işleminde başlatır ve bildirim içeriğini didReceive(_:withContentHandler:) yöntemi aracılığıyla iletir. Uzantı içeriği işler ve değiştirilmiş içerikle contentHandler'ı çağırır. Uzantı 30 saniye içinde tamamlanmazsa, sistem orijinal bildirimi görüntüler.
Service Extension, bildirim içeriğinin cihazda işlenmesi gereken senaryolarda gereklidir. Güvenli iletişim: sunucu şifrelenmiş bir payload gönderir, uzantı onu yerel olarak çözer. Zengin medya bildirimleri: sunucu bir resim URL'si gönderir, uzantı indirir ve ekler. Dinamik yerelleştirme: uzantı metni cihaz dilinde değiştirir.
| Senaryo | Uzantı olmadan | Uzantı ile |
|---|---|---|
| Resim | Desteklenmiyor | İndirilir ve görüntülenir |
| Şifreleme | Sunucu anahtarı saklar | Cihazda şifre çözme |
| Metin | Sunucuda sabit | Dinamik değiştirme |
| Doğrulama | Kontrol edilmez | Kötü amaçlı bildirimler iptal |
Notification Service Extension sınırlı bir ortamda çalışır. Maksimum yürütme süresi 30 saniyedir. Uzantının ana uygulama deposuna (App Group hariç) erişimi yoktur. Uzantı boyutu 50 MB ile sınırlıdır. Süre aşıldığında, sistem orijinal içerikle contentHandler'ı çağırır ve tüm değişiklikler kaybolur.
Xcode'da, Notification Service Extension, Notification Service Extension türünde yeni bir target oluşturularak eklenir. Xcode, UNNotificationServiceExtension'dan miras alan bir şablon NotificationService sınıfı oluşturur, iki yöntemle: didReceive ve serviceExtensionTimeWillExpire.
Xcode'da, File → New → Target → Notification Service Extension'ı seçin. Bir ad girin (örneğin, PushNotificationService) ve Swift dilini seçin. Target'ın ana uygulamaya eklendiğinden ve doğru imzaya sahip olduğundan emin olun. Oluşturulduktan sonra, NotificationService.swift sınıfı temel bir uygulama ile oluşturulacaktır.
Uzantının Info.plist'i, NSExtensionPointIdentifier (com.apple.usernotifications.service) ve NSExtensionPrincipalClass (kontrolörünüzün adı) alt anahtarlarıyla NSExtension anahtarını içerir. Ek olarak, uzantı etkinleştirme kurallarıyla NSExtensionAttributes belirtilebilir. Xcode bu ayarları otomatik olarak oluşturur.
Temel uygulama, didReceive'ı geçersiz kılar, bildirim içeriğini değiştirir ve contentHandler'ı çağırır. İşleme çok uzun sürerse, serviceExtensionTimeWillExpire çağrılır ve burada mevcut durumla işi tamamlamanız gerekir.
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 = "[İşlendi] \(bestAttemptContent.title)"
contentHandler?(bestAttemptContent)
}
}
override func serviceExtensionTimeWillExpire() {
if let contentHandler = contentHandler,
let bestAttemptContent = bestAttemptContent {
contentHandler(bestAttemptContent)
}
}
}
Service Extension'ın temel kullanımlarından biri, bildirim içeriğini cihazda şifresini çözmektir. Sunucu şifrelenmiş bir payload gönderir ve uzantı, Keychain veya App Group'da saklanan bir anahtar kullanarak şifresini çözer. Bu, içeriğin iletim sırasında ele geçirilememesini sağlar.
Sunucu, simetrik bir anahtar (AES-256) kullanarak bildirim gövdesini şifreler. Şifreleme anahtarı, istemci ve sunucu arasında önceden kararlaştırılır. Uzantı, payload'ın data alanında şifrelenmiş dizeyi alır, şifresini çözer ve bildirim alanlarına yerleştirir. Kullanıcı anahtarı, kimlik doğrulamadan sonra Keychain'den alınabilir.
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)
}
Şifre çözme anahtarı, uzantı kodunda veya NSUserDefaults'da saklanmamalıdır. Hem uygulamanın hem de uzantının anahtarı okuyabilmesi için App Group aracılığıyla erişime sahip iOS Keychain kullanın. İstemcide anahtar oluşturma için AES-256-GCM algoritmasıyla Security.framework kullanın.
Notification Service Extension'ın en yaygın kullanımı, bildirimde görüntülemek için resim, GIF ve video indirmektir. Sunucu bir medya dosyası URL'si gönderir ve uzantı onu indirir, geçici bir dizine kaydeder ve bir UNNotificationAttachment oluşturur.
Uzantı, bildirim payload alanından resim URL'sini alır. URLSession kullanarak, uzantı dosyayı geçici bir dizine indirir. İndirme tamamlandıktan sonra, yerel URL ile bir UNNotificationAttachment oluşturulur. Ek, değiştirilmiş içeriğe aktarılır. iOS otomatik olarak resmi standart arayüzde veya bir Notification Content Extension'da görüntüler.
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, bildirimlerde görüntüleme için aşağıdaki formatları destekler: JPEG, PNG, GIF (statik), 50 MB'a kadar MPEG-4 video. Ses dosyaları için MP3, AAC ve ALAC desteklenir. Önemli: tüm medya dosyaları 30 saniyelik sınır içinde indirilmelidir. Büyük dosyalar için sunucu tarafı kırpma veya aşamalı yükleme önerilir.
30 saniyelik sınırı yönetmek, Notification Service Extension geliştirirken önemli bir görevdir. Uzantı işlemeyi zamanında tamamlamazsa, sistem serviceExtensionTimeWillExpire'ı çağırır ve orijinal içeriği görüntüler. Her işleme türü için geri dönüş senaryoları sağlanmalıdır.
Görevleri önceliğe göre bölün. Önce kritik değişiklikleri (şifre çözme, temel yerelleştirme) gerçekleştirin. İsteğe bağlı iyileştirmeler (resim indirme, metin zenginleştirme) sonra gelir. Ağ istekleri için zaman aşımlı URLSession kullanarak tüm sınırı tek bir işlemde harcamayın.
Resim indirme başarısız olursa veya payload şifre çözme hata döndürürse, uzantı orijinal içerikle contentHandler'ı çağırmalıdır. ContentHandler'ı çağırmadan uzantıyı asla sonlandırmayın — bu bildirim kaybına yol açar. Güvenli bir geri dönüş her zaman uzantı kodunda sağlanmalıdır.
override func didReceive(
request: UNNotificationRequest,
withContentHandler handler: @escaping (UNNotificationContent) -> Void
) {
let content = (request.content.mutableCopy()
as? UNMutableNotificationContent) ?? request.content
// Kritik görev: şifre çözme
var decryptedContent = tryDecryptPayload(content)
// İsteğe bağlı görev: medya
guard let mediaUrl = decryptedContent.userInfo["media_url"]
as? String else {
handler(decryptedContent)
return
}
downloadAndAttachMedia(
content: decryptedContent,
mediaUrl: mediaUrl,
handler: handler
)
}
Notification Service Extension'ı test etmek için Xcode kullanın: uzantı target'ını seçin, simülatörde çalıştırın ve terminal veya Firebase Console üzerinden bir push bildirimi gönderin. os_log kullanarak işlemenin her aşamasını kaydedin — bu, zamanlama ve indirme sorunlarını teşhis etmeye yardımcı olur.
Sıkça Sorulan Sorular
Sistem serviceExtensionTimeWillExpire'ı çağırır, ardından orijinal bildirimi değişmeden görüntüler. İndirilen tüm dosyalar ve değişiklikler atılır.
Evet, boş içerikle (boş alanlarla UNNotificationContent) contentHandler'ı çağırırsanız, bildirim görüntülenmez. Bu, spam bildirimlerini veya hatalı verileri filtrelemek için kullanılır.
Token, bildirim payload'ının userInfo kısmında iletilebilir veya App Group aracılığıyla Keychain'den alınabilir. Token'ların uzantı UserDefaults'ında saklanması önerilmez.
Uzantı, ana uygulamayla aynı geliştirici sertifikasıyla imzalanmalıdır. Üretim için, Push Notifications yeteneği etkinleştirilmiş bir üretim sertifikası gereklidir.
Cihazı Xcode'a bağlayın, çalıştırma şemasında uzantı target'ını seçin ve Firebase Console üzerinden bir push bildirimi gönderin. Uzantıdaki kesme noktaları ana uygulamadaki gibi çalışır.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun