# Troubleshooting Notification Service Extensions

Verify notification service extension setup and debug issues.

If the basic verification steps do not resolve your [notification service extension](https://www.airship.com/docs/developer/sdk-integration/apple/push-notifications/notification-service-extension/) (NSE) issue, use the advanced debugging steps to isolate the cause.

## Basic verification

First, perform basic verifications:

1. Verify the deployment target includes the device you are testing it against. Airship supports 16.0+.

   ![Deployment target setting in Xcode](https://www.airship.com/docs/images/nse-troubleshoot-deployment-version_hu_5e5f95dfb9a1775e.webp)
   
   *Deployment target setting in Xcode*

1. Verify the extension target links the `AirshipNotificationServiceExtension` framework and none of the other Airship frameworks.

   ![Extension target linked to AirshipNotificationServiceExtension only](https://www.airship.com/docs/images/extension-target-links-airship-notification-service-extension_hu_a3504fa3a2c481b6.webp)
   
   *Extension target linked to AirshipNotificationServiceExtension only*

1. Verify the main app target links to your extension.

   ![Main app target embedding the extension](https://www.airship.com/docs/images/main-app-target-extension_hu_fed870069ef4ef29.webp)
   
   *Main app target embedding the extension*

1. 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:

1. 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.

   
#### Swift


   ```swift
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)
           }
       }

   }
```

   


1. Confirm the extension can modify the title when using Apple's default implementation.

1. 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.

   
#### Swift


   ```swift
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)
           }
       }

   }
```

   


1. Confirm you still receive the modified title. This verifies the Airship NSE framework is linked correctly.

1. Remove the title-modification test code and implement the full Airship NSE integration.

   
#### Swift


   ```swift
import UserNotifications
   import AirshipNotificationServiceExtension

   class NotificationService: UANotificationServiceExtension {
   }
```

   


1. Test that rich media, such as images, displays correctly.

1. Add verbose logging to troubleshoot the issue if none of these steps resolved the issue.

   
#### Swift


   ```swift
import UserNotifications
   import AirshipNotificationServiceExtension

   class NotificationService: UANotificationServiceExtension {
       override var airshipConfig: AirshipExtensionConfig {
           return AirshipExtensionConfig(
               logLevel: .verbose,
               logHandler: .publicLogger
           )
       }
   }
```

   

