Integrate the Android SDK
Configure the Service Extension
Configure the Content Extension
Configure Carousel Click Actions
Enable App Groups
Runtime Toggles
Integrate with Other Platforms
Handle URLs
Changelog
Set up the Notification Service Extension to enable push delivery tracking.
The notification service extension runs as a separate bundle within your main app.
In Xcode, go to File > New > Target.
In the iOS > Application Extension section, select Notification Service Extension.
Click Next.
Configure the app extension and click Finish.
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.

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.
Important
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.
Important
Integrate the iOS Extension SDK using Swift Package Manager.
To integrate the extension SDK manually:
Download these SDKs:
Copy the relevant .xcframework directories from your downloads folder into your project folder.
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.
Add MarketingCloudSDK.bundle to Copy Bundle Resources under Build Phases.
In Build Settings, add -ObjC to Other Linker Flags.
Remove the autogenerated code from your Service Extension class and inherit from SFMCNotificationService.
1import UserNotifications
2import MCExtensionSDK
3
4class NotificationService: SFMCNotificationService { }1#import <UserNotifications/UserNotifications.h>
2#import <MCExtensionSDK/MCExtensionSDK.h>
3
4@interface NotificationService : SFMCNotificationService
5
6@end1#import "NotificationService.h"
2
3@implementation NotificationService
4
5@endDon’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.
Warning
The MCExtensionSDK manages the UNNotificationServiceExtension lifecycle methods. Customize the extension’s behavior to:
userInfoEnable 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.
1override func sfmcProvideConfig() -> SFNotificationServiceConfig {
2 return SFNotificationServiceConfig(logLevel: .debug, shouldShowCarouselThumbnail: false)
3}1- (SFMCNotificationServiceConfig *)sfmcProvideConfig {
2 return [[SFMCNotificationServiceConfig alloc] initWithLogLevel:SFMCExtensionSdkLogLevelDebug shouldShowCarouselThumbnail:NO];
3}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.
1import UserNotifications
2import MCExtensionSDK
3
4class NotificationService: SFMCNotificationService {
5
6 // Use this method to enable logging or 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 to do custom processing, such as image and video downloads or inserting
16 // custom keys in notification userInfo.
17 // Don’t modify `mutableContent.request.content.userInfo` directly. If you need to add a custom
18 // key in notification userInfo, return a dictionary in the completion handler.
19 // The system provides limited time to perform your processing operation.
20 override func sfmcDidReceive(_ request: UNNotificationRequest, mutableContent: UNMutableNotificationContent, withContentHandler contentHandler: @escaping ([AnyHashable : Any]?) -> Void) {
21 // Your custom code here
22
23 // To add custom key/value pairs in the notifications userInfo object, update this line.
24 var customUserInfo: [AnyHashable : Any] = [:]
25 customUserInfo["MyCustomKey"] = "MyCustomValue"
26
27 // Call the content handler to signal the end of your processing operation.
28 contentHandler(customUserInfo)
29 }
30}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 to do custom processing, such as image and video downloads or inserting
15// custom keys in notification userInfo.
16// Don’t modify `mutableContent.request.content.userInfo` directly. If you need to add a custom
17// key in notification userInfo, return a dictionary in the completion handler.
18// The system provides limited time to perform your processing operation.
19- (void)sfmcDidReceiveRequest:(UNNotificationRequest *)request
20 mutableContent:(UNMutableNotificationContent *)mutableContent
21 withContentHandler:(void (^)(NSDictionary * __nullable))contentHandler {
22 // Your custom code here
23
24 // To add custom key/value pairs in the notifications userInfo object, update this line.
25 NSDictionary *customUserInfo = @{@"MyCustomKey": @"MyCustomValue"};
26
27 // Call the content handler to signal the end of your processing operation.
28 contentHandler(customUserInfo);
29}
30
31@endWhen 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.
Important