So currently I'm doing this:
override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
logger = AnalyticsManager.shared
self.contentHandler = contentHandler
bestAttemptContent = (request.content.mutableCopy() as! UNMutableNotificationContent)
if let notificationContent = bestAttemptContent {
extensionHandler = ServiceExtensionHandler(notificationContent: notificationContent, logger: AnalyticsManager.shared)
extensionHandler?.handleNotificationRequest { modifiedNotificationContent in
guard let modifiedNotificationContent = modifiedNotificationContent else {
contentHandler(notificationContent)
return
}
contentHandler(modifiedNotificationContent)
}
} else {
contentHandler(request.content)
return
}
}
In my ServiceExtensionHandler if image download succeeds, I'll return the modified notification. So far so good.
But once the image download succeeds, I want to log an event.
Problem is if I return the contentHandler then the OS will kill the extension and I won't have time to complete my log.
Shortly after the app extension performs its task (or starts a background session to perform it), the system terminates the extension.
At the moment it's working but that extra network call isn't guaranteed to work.
I could only return that completionHandler if the log returns, but then well the log could timeout in 60 seconds and that's another problem in itself as well.
Has anyone thought of any solutions for this?
You're on the right track.
You should return the
contentHandlerultimately from a callback that is derived off of the logging's network callback. Just with a minor change:For your log's network call, set its
URLSessionConfigurationstimeoutIntervalForRequestto something lower than 5 seconds. This way you don't wait to long for it to complete.This is pseudo code, but for the object that does the logging do something like:
It either succeeds/fails in less than 5 seconds or if it's going to timeout, it won't take any longer than 5 seconds.