Troubleshooting Notification Service Extensions
Verify notification service extension setup and debug issues.
If the basic verification steps do not resolve your notification service extension (NSE) issue, use the advanced debugging steps to isolate the cause.
Basic verification
First, perform basic verifications:
Verify the deployment target includes the device you are testing it against. Airship supports 16.0+.

Deployment target setting in Xcode Verify the extension target links the
AirshipNotificationServiceExtensionframework and none of the other Airship frameworks.
Extension target linked to AirshipNotificationServiceExtension only Verify the main app target links to your extension.

Main app target embedding the extension Verify the extension bundle ID follows the app bundle ID with a suffix. For example,
com.example.app.NotificationServiceExtension.
Advanced debugging
If issues persist, isolate the problem by building up from Apple’s default implementation:
Replace your NSE implementation with Apple’s default NSE that only modifies the notification title. If that fails, recreate the extension and repeat the basic verification steps.
Apple's default NSE
import UserNotifications class NotificationService: UNNotificationServiceExtension { var contentHandler: ((UNNotificationContent) -> Void)? var bestAttemptContent: UNMutableNotificationContent? override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { self.contentHandler = contentHandler bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) if let bestAttemptContent = bestAttemptContent { // Modify the notification content here... bestAttemptContent.title = "\(bestAttemptContent.title) [modified]" contentHandler(bestAttemptContent) } } override func serviceExtensionTimeWillExpire() { // Called just before the extension will be terminated by the system. // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { contentHandler(bestAttemptContent) } } }Confirm the extension can modify the title when using Apple’s default implementation.
Link the Airship NSE framework to your extension and have your NSE extend the Airship NSE class instead of
UNNotificationServiceExtension. Keep your existing title-modification logic for now.Default NSE that extends Airship
import UserNotifications import AirshipNotificationServiceExtension class NotificationService: UANotificationServiceExtension { var contentHandler: ((UNNotificationContent) -> Void)? var bestAttemptContent: UNMutableNotificationContent? override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) { self.contentHandler = contentHandler bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent) if let bestAttemptContent = bestAttemptContent { // Modify the notification content here... bestAttemptContent.title = "\(bestAttemptContent.title) [modified]" contentHandler(bestAttemptContent) } } override func serviceExtensionTimeWillExpire() { // Called just before the extension will be terminated by the system. // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used. if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent { contentHandler(bestAttemptContent) } } }Confirm you still receive the modified title. This verifies the Airship NSE framework is linked correctly.
Remove the title-modification test code and implement the full Airship NSE integration.
Implement the full Airship NSE integration
import UserNotifications import AirshipNotificationServiceExtension class NotificationService: UANotificationServiceExtension { }Test that rich media, such as images, displays correctly.
Add verbose logging to troubleshoot the issue if none of these steps resolved the issue.
Add verbose logging
import UserNotifications import AirshipNotificationServiceExtension class NotificationService: UANotificationServiceExtension { override var airshipConfig: AirshipExtensionConfig { return AirshipExtensionConfig( logLevel: .verbose, logHandler: .publicLogger ) } }