Я разрабатываю систему push-уведомлений для приложения IOS. Есть некоторые требования, которые я хочу выполнить.
Возможность локально изменять заголовок и текст push.
В центре уведомлений отображаются только самые последние уведомления по идентификатору. Поэтому, если устройство получает 2 push-уведомления с одним и тем же идентификатором, второе должно заменить первое в центре уведомлений.
Возможность отправлять push, даже когда приложение принудительно убито.
Использование UNNotificationServiceExtension
При использовании ServiceExtension я могу изменить содержимое, но не могу изменить идентификатор запроса, поскольку это свойство только для получения. В результате мой центр уведомлений не заменяет старые уведомления новыми.
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
if var bestAttemptContent = bestAttemptContent {
// Modify the notification content here... sweet!
bestAttemptContent.title = "\(bestAttemptContent.title) [modified]"
//resolveNotificationContent(content: &bestAttemptContent)
//getDeliveredNotifications always returns an empty array of notifications
UNUserNotificationCenter.current().getDeliveredNotifications{ notifications in
print("notifications: \(notifications)")
}
contentHandler(bestAttemptContent)
}
}
Использование Silent Notification
Моя другая идея - отправить молчаливое уведомление и вручную создать уведомление «Не молчать» локально, вот так.
//Called when the user recieves a notifiation and the app is in the background
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
log.info()
defer {
completionHandler(.noData)
}
//if app is active, return
if application.applicationState == .active {
return
}
guard let content = PushNotification.createNotificationContent(from: userInfo) else {
return
}
guard let notificationData = content.userInfo["data"] as? [String: Any] else {
log.error("failed to convert 'aps' value to Dict<String:Any>")
return
}
let pushData = PushNotification.resolveNotification(from: notificationData)
var identifier = ""
if pushData != nil {
identifier = pushData!.getIdentifier()
}
let request = UNNotificationRequest(identifier: identifier, content: content, trigger: nil)
UNUserNotificationCenter.current().add(request) { (error) in
self.log.error(error)
}
}
Проблема в том, что мое тихое уведомление никогда не доставляется, когда приложение принудительно убивается (имеет смысл).
Есть ли способ выполнить все 3 требования?