The MobilePush SDK version 9.0.0 introduced Push Delivery events and a Carousel template. To use these features, add the Service Extensions and Content Extensions targets in your app. Next, integrate the iOS Extension SDK MCExtensionSDK.
Prerequisites
To integrate the MobilePush SDK Extension for iOS, you need:
Service and Content Extension targets in your main app.
This section shows how to 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 separate bundle within the main app. To add a service extension target, perform these steps.
In Xcode, go to File > New > Target.
From 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 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 MobilePush SDK Extension for iOS with the Service Extension, choose a method based on your project setup and preference.
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) build settings.
Note
Open your application project, select the Service Extension target, and add MCExtensionSDK to the Frameworks, Libraries, and Embedded Content section in the target’s General settings.
Inherit from SFMCNotificationService
Remove all autogenerated code and inherit the main class of the Service Extension from the SFMCNotificationService class.
Make sure that you don’t implement any UNNotificationServiceExtension methods, such as func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) → Void) and open func serviceExtensionTimeWillExpire()
Warning
Additional Configuration Options
The MCExtensionSDK manages the UNNotificationServiceExtension lifecycle methods. However, you may need to customize behavior, such as:
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, override the sfmcProvideConfig() method: override func sfmcProvideConfig() → SFNotificationServiceConfig
Configure Thumbnail
To enable or disable the first image of the Carousel template as a thumbnail, override the sfmcProvideConfig() method. Then, set the value of shouldShowCarouselThumbnail to true or false. This is available starting with version 9.0.1.
The shouldShowCarouselThumbnail value is true by default unless you override it.
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.
Swift example
1import UserNotifications2import MCExtensionSDK34class NotificationService: SFMCNotificationService {56 // Please use this method to enable logging, change logging levels etc, if required7 override func sfmcProvideConfig() -> SFNotificationServiceConfig {8 var logLevel: LogLevel = .none9#if DEBUG10 logLevel = .debug11#endif12 return SFNotificationServiceConfig(logLevel: logLevel)13}1415 // Please use this method if and only if you need to do any custom processing e.g. image, video download, inserting custom keys in notification userInfo etc16 // Please don’t modify `mutableContent.request.content.userInfo` directly as doing so may result in exception17 // If you need to add any custom key in notification userInfo, then please return a dictionary in the completion handler181920 // Please note that like the `UNNotificationServiceExtension` method - func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) → Void),21 // you will only get limited time from system to perform your processing operation22 override func sfmcDidReceive(_ request: UNNotificationRequest, mutableContent: UNMutableNotificationContent, withContentHandler contentHandler: @escaping([AnyHashable : Any]?) ->Void){23 // Your custom code here24 //...2526 // In case you need to add any custom key/value pair(s) in notifications userInfo object then27 var customUserInfo: [AnyHashable : Any] = [:]28 customUserInfo["MyCustomKey"] = "MyCustomValue"2930 // Finally call content handler to signal end of your processing operation31 //32 contentHandler(customUserInfo)33}34}
Here’s an example of an Objective-C-based implementation where SFMCNotificationService is extended to configure logging using sfmcProvideConfig and handle custom push notification processing using sfmcDidReceiveRequest:mutableContent:withContentHandler:, enabling actions such as adding custom key-value pairs to the notification payload.
Objective-C example
1#import "NotificationService.h"23@implementation NotificationService45// Please use this method to enable logging, change logging levels etc, if required6- (SFMCNotificationServiceConfig *)sfmcProvideConfig {7 SFMCExtensionSdkLogLevel logLevel = SFMCExtensionSdkLogLevelNone;8#if DEBUG9 logLevel = SFMCExtensionSdkLogLevelDebug;10#endif11 return [[SFMCNotificationServiceConfig alloc] initWithLogLevel: logLevel];12}1314// Please use this method if and only if you need to do any custom processing e.g. image, video download, inserting custom keys in notification userInfo etc15// Please don’t modify `mutableContent.request.content.userInfo` directly as doing so may result in exception16// If you need to add any custom key in notification userInfo, then please return a dictionary in the completion handler1718// Please note that like the `UNNotificationServiceExtension` method: - (void) didReceiveNotificationRequest:(UNNotificationRequest *) request19// withContentHandler:(void (^)(UNNotificationContent * contentToDeliver)) contentHandler,20// you will only get limited time from system to perform your processing operation21- (void)sfmcDidReceiveRequest:(UNNotificationRequest *)request22 mutableContent:(UNMutableNotificationContent *)mutableContent23 withContentHandler:(void (^)(NSDictionary * __nullable))contentHandler {24 // Your custom code here25 //...2627 // In case you need to add any custom key/value pair(s) in notifications userInfo object then28 NSDictionary *customUserInfo = @{@"MyCustomKey": @"MyCustomValue"};2930 // Finally call content handler to signal end of your processing operation31 contentHandler(customUserInfo);32}3334@end
While customizing the func sfmcDidReceive(_ request: mutableContent: withContentHandler:), don’t modify mutableContent.request.content.userInfo directly, as this can cause an exception. Instead, use contentHandler to add custom key-value pairs, as shown in the examples. Since the content extension has a limited runtime, minimize the custom processing time. Additionally, make sure that the completion handler is invoked along every possible return path.
Warning
Configure the Content Extension
To display rich media notifications, you must add and configure a Content Extension to your project.
Add a Content Extension Target
Notification Content Extensions run as separate processes within your app, providing isolation and enhancing security. Follow these steps to add a content extension target.
In Xcode, go to File > New > Target.
From the iOS > Application Extension section, select Notification Content Extension.
Click Next.
Provide a name and configure your extension settings.
Click Finish.
Verify that the newly created extension is listed under the Frameworks, Libraries, and Embedded Content section of your target’s General settings. If it’s not present, add it manually.
Integrate the Extension SDK with Your Content Extension
After successful integration, confirm that the library is listed within the Frameworks, Libraries, and Embedded Content section of your Content Extension’s target settings.
Inherit from SFMCNotificationViewController
Remove all Apple-generated boilerplate code and inherit the main class of the Content Extension from SFMCNotificationViewController, as shown in these examples.
SFMCNotificationViewController fully manages UI rendering. Don’t implement or override any UIViewController methods in the principal class of the content extension, as doing so can interfere with UI rendering.
Configure your project and content extension’s Info.plist file to register the correct notification category, build the rich push notification UI in code using the Extension SDK, and enable user interaction. These steps ensure the content extension is correctly triggered and displays the intended rich UI as defined in Marketing Cloud Engagement.
Set Up the Extension Category
To set up and synchronize the notification category between your content extension’s Info.plist file and the Marketing Cloud Engagement UI, perform these steps.
Contact your Marketing Cloud Engagement admin to obtain the correct category name for the Rich UI template.
In your content extension’s Info.plist file, replace the value for UNNotificationExtensionCategory under NSExtension > NSExtensionAttributes. For illustrative purposes, the category is set to AwesomeAppRichUICategory in the screenshot in the next section.
iOS activates the content extension only if the category value in the push notification payload matches the one defined in Info.plist > NSExtension > NSExtensionAttributes > UNNotificationExtensionCategory. Make sure that the category value in Marketing Cloud Engagement matches the value in your content extension’s Info.plist file. Otherwise, the Carousel template won’t show.
Warning
Build the UI Programmatically
Unlike Apple’s auto-generated content extension template, MCExtensionSDK builds the notification UI programmatically instead of using an Interface Builder file. Follow these steps to modify the project to build the rich push notification UI entirely in code using the MCExtensionSDK, instead of using a storyboard.
Remove the storyboard reference by deleting the NSExtensionMainStoryboard item from Info.plist > NSExtension.
Add the NSExtensionPrincipalClass key to Info.plist > NSExtension
Value type: String
Value: $(PRODUCT_MODULE_NAME).<MainClassName>
For Objective-C project, specify the class name directly.
Note
Remove MainInterface.storyboard from your project.
Enable User Interaction
Add this key to your content extension’s Info.plist file.
This screenshot illustrates an Info.plist file in a Swift-based implementation with configured NSExtensionAttributes and NSExtensionPrincipalClass.
This screenshot illustrates an Info.plist file in an Objective-C-based implementation with configured NSExtensionAttributes and NSExtensionPrincipalClass.
Additional Configuration
You can further customize extension behavior by:
Configuring logging
Adjusting the HTTP request timeout
For Swift-based implementations, implement the sfmcProvideConfig() method to define custom log levels and HTTP timeout settings for the extension.
The default timeout for network requests is 15 seconds. Additionally, iOS blocks insecure (non-HTTPS) URLs by default. To allow loading Carousel images from HTTP URLs, configure an exception.
Note
Enable App Groups Capability
The Main App, Service Extension, and Content Extension run in three separate processes. iOS limits inter-process communication (IPC) between the extensions and the main app. To ensure that Push Delivery events and the Carousel template work as intended, the MobilePush iOS SDK and the MobilePush iOS Extension SDK rely on the App Groups capability.
Configure App Groups for the Main App Target
Select your main app target and navigate to the Signing & Capabilities tab.
Add the App Groups capability.
Add a new app group container or use an existing one. Note down this container name. If you’re creating a new container, we recommend using a name in this format:
group.<bundle-id>.sfmarketingcloudsdk
Add the container name to a new Info.plist key with these details:
Info.plist value: The app group container name (for example, group.com.salesforce.MyAwesomeApp.sfmarketingcloudsdk)
Configure App Groups for the Extension Targets
Repeat the steps listed in the previous section to add app groups for your Service Extension and Content Extension targets. When adding app groups, make sure you use the same container name as prescribed in the previous step. Additionally, update each extension’s Info.plist with the same SF_MARKETINGCLOUD_APP_GROUP_KEY key and value used in the main app.
Make sure that SF_MARKETINGCLOUD_APP_GROUP_KEY value is identical in all three Info.plist files: Main App, Service extension, and Content Extension.