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 contentHandler
ultimately 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 URLSessionConfiguration
s timeoutIntervalForRequest
to 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:
if let imageData = data {
self?.log("downloadSuccess") {
completionHandler(imageData, nil)
}
}
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.