Configure the Service Extension for the iOS Extension SDK

Set up the Notification Service Extension to enable push delivery tracking.

The notification service extension runs as a separate bundle within your main app.

  1. In Xcode, go to File > New > Target.

  2. In the iOS > Application Extension section, select Notification Service Extension.

  3. Click Next.

  4. Configure the app extension and click Finish.

  5. In your project target’s General settings, verify that the new extension is listed under Frameworks, Libraries, and Embedded Content. If it’s not there, add it.

    The Frameworks, Libraries, and Embedded Content section for a project, showing the new extension highlighted.

    Use the same Xcode-managed profile for the extension targets as your main app. Match the service extension version to the main app version, and prefix the service extension bundle ID with the main app’s bundle ID. For example, if your main app’s bundle ID is com.salesforce.MyAwesomeApp, use com.salesforce.MyAwesomeApp.MyServiceExtension for the service extension.

Choose an integration method based on your project setup.

Add the SDK as a dependency in your app’s Podfile. Follow the instructions for Adding pods to an Xcode project in the CocoaPods documentation.

After installation completes, open the .xcworkspace file that CocoaPods created.

Avoid opening .xcodeproj directly. Opening a project file instead of a workspace can lead to errors.

Integrate the iOS Extension SDK using Swift Package Manager.

  1. In Xcode, open your project and select Project Settings.
  2. Go to the Package Dependencies tab, and click + to add a new package.
  3. Enter the repository URL and add these packages required for your implementation:
  4. Review the package details and confirm to complete the installation.

To integrate the extension SDK manually:

  1. Download these SDKs:

  2. Copy the relevant .xcframework directories from your downloads folder into your project folder.

  3. In Xcode, open your project and select the appropriate target. Add the required .xcframework files to Frameworks, Libraries, and Embedded Content in the target’s General settings.

  4. Add MarketingCloudSDK.bundle to Copy Bundle Resources under Build Phases.

  5. In Build Settings, add -ObjC to Other Linker Flags.

Remove the autogenerated code from your Service Extension class and inherit from SFMCNotificationService.

View Swift code example
View Objective-C code example

Don’t implement any UNNotificationServiceExtension methods, such as func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) → Void) and open func serviceExtensionTimeWillExpire(). The SFMCNotificationService class handles these methods.

The MCExtensionSDK manages the UNNotificationServiceExtension lifecycle methods. Customize the extension’s behavior to:

  • Enable or disable logging and configure log levels
  • Download and attach images or videos to push notifications
  • Add custom key-value pairs to the notification’s userInfo
  • Perform other operations your app requires

Enable or disable logging and configure log levels by overriding the sfmcProvideConfig() method: override func sfmcProvideConfig() → SFNotificationServiceConfig

Show the first image of a carousel as a thumbnail by overriding the sfmcProvideConfig() method and setting shouldShowCarouselThumbnail to false.

View Swift code example
View Objective-C code example

Execute custom code by overriding func sfmcDidReceive(_ request: UNNotificationRequest, mutableContent: UNMutableNotificationContent, withContentHandler contentHandler: @escaping ([AnyHashable : Any]?) → Void). Use this method to process notifications, download media, or add custom key-value pairs.

These examples show how to configure logging and customize notification handling.

View Swift code example
View Objective-C code example

When you customize func sfmcDidReceive(_ request: mutableContent: withContentHandler:), don’t modify mutableContent.request.content.userInfo directly. Use contentHandler to add custom key-value pairs. The system provides limited time for processing, so minimize custom processing time and invoke the completion handler on every return path.