Configure the Service Extension for the iOS Extension SDK

Setup and configure the Notification Service Extension for use with the iOS Extension SDK.

Add a Service Extension Target 

The notification service app extension is a bundle within your main app. To add a service extension target, complete these steps.

  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 the General Settings section for your project target, verify that the new extension is listed under Frameworks, Libraries, and Embedded Content. If it isn’t listed there, add it.

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

    Important

Integrate the Extension SDK with the Service Extension 

To integrate the Service Extension, add the dependencies to CocoaPods or Swift Package Manager (SPM). You can also add the dependencies manually.

Integrate the Extension SDK with CocoaPods 

If you use CocoaPods to manage dependencies for your app, add the extension SDK to your Podfile.

  1. Update your Podfile to include the extension SDK.
1target '<appTarget>' do
2  use_frameworks!
3  pod 'MarketingCloudSDK'
4end
5
6target '<appExtensionTarget>' do
7  use_frameworks!
8  pod 'MarketingCloud-ExtensionSDK'
9end
  1. In your project directory, run pod install.
  2. Open the .xcworkspace file that CocoaPods generates.

Don’t open the .xcodeproj file directly. Opening a project file instead of a workspace can lead to errors.

Important

For more information about updating Podfiles, see Using CocoaPods: Adding pods to an Xcode project on the CocoaPods documentation site.

Integrate the Extension SDK with Swift Package Manager 

If you use Swift Package Manager (SPM) to manage dependencies for your app, add the extension SDK to your Podfile.

  1. On the Package Dependencies tab of your project’s settings, click the plus sign (+) to add a package.
  2. Search for the package MCExtensionSDK using the URL https://github.com/salesforce-marketingcloud/extension-sdk-ios.git
  3. Select the package to include it in your app.

Integrate the Extension SDK Manually 

If you don’t use CocoaPods or Swift Package Manager, you can add the extension packages manually.

  1. Download the MCExtensionSDK.

  2. Copy the MCExtensionSDK directory from your downloads folder to your project directory.

    To keep the binary in a different location, adjust the Framework Search Path (FRAMEWORK_SEARCH_PATHS) in your build settings.

    Note

  3. In your project, select the Service Extension target

  4. In the General Settings for your project, in the Frameworks, Libraries, and Embedded Content section, add the MCExtensionSDK framework.

Inherit from SFMCNotificationService 

After you add the dependencies to your project, inherit the main class of the Service Extension from the SFMCNotificationService class.

If your project is written in Swift, use this code to inherit the service.

1import UserNotifications
2import MCExtensionSDK
3
4class NotificationService: SFMCNotificationService { }

If your project uses ObjectiveC, use this header.

1#import <UserNotifications/UserNotifications.h>
2#import <MCExtensionSDK/MCExtensionSDK.h>
3
4@interface NotificationService : SFMCNotificationService
5
6@end

In your ObjectiveC implementation file, use this code.

1#import "NotificationService.h"
2
3@implementation NotificationService
4
5@end

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

Warning

Additional Configuration Options 

The MCExtensionSDK manages the UNNotificationServiceExtension lifecycle methods. You can customize some of the ways the extension behaves.

  • Enabling or disabling logging and configuring log levels
  • Downloading and attaching images or videos to push notifications
  • Adding custom key-value pairs to the notification’s userInfo
  • Performing other necessary operations

Configure Logging 

To enable or disable logging and configure log levels, use this code to override the sfmcProvideConfig() method:

1override func sfmcProvideConfig() → SFNotificationServiceConfig

Configure Thumbnail 

To enable or disable the first image of the Carousel template as a thumbnail, use this code to override the sfmcProvideConfig() method.

Swift example
1override func sfmcProvideConfig() -> SFNotificationServiceConfig {
2    return SFNotificationServiceConfig(logLevel: .debug, shouldShowCarouselThumbnail: false)
3}

Next, set the value of the shouldShowCarouselThumbnail property. This property is true by default.

This property is available in version 9.0.1 and later.

Objective-C example
1- (SFMCNotificationServiceConfig *)sfmcProvideConfig {
2 return [[SFMCNotificationServiceConfig alloc] initWithLogLevel:SFMCExtensionSdkLogLevelDebug shouldShowCarouselThumbnail:NO];
3}

Execute Custom Code 

To execute custom code, override func sfmcDidReceive(_ request: UNNotificationRequest, mutableContent: UNMutableNotificationContent, withContentHandler contentHandler: @escaping ([AnyHashable : Any]?) → Void) to process notifications, such as downloading media or adding custom key-value pairs.

This code example depicts a Swift-based implementation where SFMCNotificationService is extended to configure logging through sfmcProvideConfig() and customize push notification handling in sfmcDidReceive(_:mutableContent:withContentHandler:), allowing for operations like adding custom key-value pairs.

View this code example
1import UserNotifications
2import MCExtensionSDK
3
4class NotificationService: SFMCNotificationService {
5
6    // Use this method to enable logging and change logging levels.
7    override func sfmcProvideConfig() -> SFNotificationServiceConfig {
8        var logLevel: LogLevel = .none
9#if DEBUG
10        logLevel = .debug
11#endif
12        return SFNotificationServiceConfig(logLevel: logLevel)
13    }
14
15    // Use this method only when you need to do custom processing.
16    // Don’t modify mutableContent.request.content.userInfo directly.
17    // To add a custom key in notification userInfo, then return a dictionary in the completion handler.
18
19    // Like the `UNNotificationServiceExtension` method - func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) → Void),
20    // the system limits the amount of time that can be allocated to performing the processing operation.
21    override func sfmcDidReceive(_ request: UNNotificationRequest, mutableContent: UNMutableNotificationContent, withContentHandler contentHandler: @escaping ([AnyHashable : Any]?) -> Void) {
22        // Your custom code here
23
24        // Add custom key-value pairs here
25        var customUserInfo: [AnyHashable : Any] = [:]
26        customUserInfo["MyCustomKey"] = "MyCustomValue"
27
28        // Call the content handler to signal the end of your processing operation.
29        contentHandler(customUserInfo)
30    }
31}

This example shows an Objective-C-based implementation where SFMCNotificationService is extended to configure logging and handle custom push notification processing.

View this code example
1#import "NotificationService.h"
2
3@implementation NotificationService
4
5// Use this method to enable logging and change logging levels
6- (SFMCNotificationServiceConfig *)sfmcProvideConfig {
7    SFMCExtensionSdkLogLevel logLevel = SFMCExtensionSdkLogLevelNone;
8#if DEBUG
9    logLevel = SFMCExtensionSdkLogLevelDebug;
10#endif
11    return [[SFMCNotificationServiceConfig alloc] initWithLogLevel: logLevel];
12}
13
14// Use this method only when you need to do custom processing.
15// Don’t modify mutableContent.request.content.userInfo directly.
16// To add a custom key in notification userInfo, then return a dictionary in the completion handler.
17
18  // Like the `UNNotificationServiceExtension` method - func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) → Void),
19  // the system limits the amount of time that can be allocated to performing the processing operation.
20- (void)sfmcDidReceiveRequest:(UNNotificationRequest *)request
21               mutableContent:(UNMutableNotificationContent *)mutableContent
22           withContentHandler:(void (^)(NSDictionary * __nullable))contentHandler {
23    // Your custom code here
24    //...
25
26    // Add custom key-value pairs here
27    NSDictionary *customUserInfo = @{@"MyCustomKey": @"MyCustomValue"};
28
29    // Call the content handler to signal the end of your processing operation.
30    contentHandler(customUserInfo);
31}
32@end