Integrate the iOS SDK

You can integrate the MobilePush SDK into your iOS app to enable push notifications and user engagement features.

There are three ways to implement the SDK:

Implement the SDK with CocoaPods 

To add the SDK as a dependency in your app’s Podfile, add the pod to your Xcode project. See Using CocoaPods: Adding Pods to an Xcode project.

11.x
1target 'MyApp' do
2  pod 'MarketingCloudSDK'
3  pod 'SFPushFeatureSDK'
4  pod 'SFInAppMessagingFeatureSDK'
5end
10.x
1target 'MyApp' do
2  pod 'MarketingCloudSDK'
3  pod 'SFPushFeatureSDK'
4end
8.x
1target 'MyApp' do
2  pod 'MarketingCloudSDK'
3end

Next, open the .xcworkspace created by the install process using Xcode and start using the SDK.

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

Important

Implement the SDK with Swift Package Manager 

Starting with version 8.0.0 of the MobilePush SDK, you can implement the SDK using Swift Package Manager (SPM).

  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.

For information about migrating from older versions of the SDK, see Migrate and Upgrade the MobilePush SDK

Implement the SDK Manually 

To implement the SDK manually, complete these steps.

  1. Download the latest versions of the required frameworks:

  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. In Build Settings, add -ObjC to Other Linker Flags.

Configure the SDK 

For reference documentation on SDK configuration methods, refer to these links:

The configuration example in this section uses the MarketingCloudSDK ConfigBuilder configuration method, as it’s the most flexible means to support your application’s usage of the MobilePush SDK.

Configuring the SDK using a JSON file is deprecated. Move existing implementations to the builder method. For more information about configuration methods, see the MarketingCloudSDKConfigBuilder reference for SDK version 7 and later, and the PushConfigBuilder reference for SDK versions 8 and later.

Important

All method names contain the prefix sfmc_. This convention allows the application implementing the SDK to avoid namespace collisions between the external libraries it uses. The MarketingCloudSDK doesn’t cause compile, link, or runtime collisions with other code your application implements. For more information, see Apple Developer Documentation: Customizing Existing Classes.

Configure the SDK in your application using the Access Token, App ID, App Endpoint, and MID values noted when you Retrieve Required SDK Configuration Data.

SDK for iOS, version 10 or higher
1import MarketingCloudSDK
2import SFMCSDK
3import UIKit
4
5@main
6class AppDelegate: UIResponder, UIApplicationDelegate {
7
8  var window: UIWindow?
9
10  // Marketing Cloud SDK Configuration
11  let mcAppID = "<your MC appID here>"
12  let mcAccessToken = "<your MC accessToken here>"
13  let mcServerURL = "<your mc serverURL here>"
14  let mcMid = "<your account MID here>"
15
16  // Define features of Marketing Cloud your app will use.
17  let mcInboxEnabled = false
18  let mcLocationEnabled = false
19  let mcAnalyticsEnabled = true
20
21  // MarketingCloud SDK: REQUIRED IMPLEMENTATION
22  @discardableResult
23
24  func configureSdk() -> Bool {
25
26    // Enable logging for debugging early on. Debug level is not recommended for production apps, as significant data
27    // about the SDK will be logged to the console.
28
29    #if DEBUG
30      SFMCSdk.setLogger(logLevel: .debug)
31    #endif
32
33    // Use the `MarketingCloudSdkConfigBuilder` to configure the MarketingCloud SDK. This gives you the maximum flexibility in SDK configuration.
34    // The builder lets you configure the module parameters at runtime.
35
36    let engagementConfiguration = MarketingCloudSdkConfigBuilder(appId: mcAppID)
37      .setAccessToken(mcAccessToken)
38      .setMarketingCloudServerUrl(URL(string: mcServerURL)!)
39      .setMid(mcMid)
40      .setInboxEnabled(mcInboxEnabled)
41      .setLocationEnabled(mcLocationEnabled)
42      .setAnalyticsEnabled(mcAnalyticsEnabled)
43      .build()
44
45    // Set the completion handler to take action when all modules initialization is completed.
46    // Seting the completion handler is optional.
47
48    let completionHandler: ((_ status: [ModuleInitStatus]) -> Void) = { [weak self] status in
49      DispatchQueue.main.async {
50        self?.handleSDKInitializationCompletion(status: status)
51      }
52    }
53
54    SFMCSdk.initializeSdk(
55      ConfigBuilder().setEngagement(config: engagementConfiguration).build(),
56      completion: completionHandler)
57
58    return true
59  }
60
61  // MARK: - SDK Initialization Completion Handler
62
63  private func handleSDKInitializationCompletion(status: [ModuleInitStatus]) {
64    var allSuccessful = true
65
66    for moduleStatus in status {
67      print(
68        "Module: \(moduleStatus.moduleName.rawValue), Status: \(moduleStatus.initStatus.rawValue)")
69
70      if moduleStatus.initStatus == .success {
71        // Handle successful initialization for each module
72        switch moduleStatus.moduleName {
73        case .engagement:
74          // Handle successful initialization for Marketing cloud module
75        default:
76          break
77        }
78      } else if moduleStatus.initStatus == .error {
79        allSuccessful = false
80        // module failed to initialize, check logs for more details
81      } else if moduleStatus.initStatus == .cancelled {
82        allSuccessful = false
83        // module initialization was cancelled (for example due to re-confirguration triggered before init was completed)
84      } else if moduleStatus.initStatus == .timeout {
85        allSuccessful = false
86        // module failed to initialize due to timeout, check logs for more details
87      }
88    }
89    if allSuccessful {
90      print("SDK initialization completed successfully")
91    } else {
92      print("SDK initialization completed with errors - check logs above")
93    }
94  }
95
96  func application(
97    _ application: UIApplication,
98    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
99  ) -> Bool {
100    // Override point for customization after application launch.
101    self.configureSdk()
102    return true
103  }
104
105  // Marketing Cloud SDK: OPTIONAL IMPLEMENTATION (if using Data Protection)
106  func applicationProtectedDataDidBecomeAvailable(_ application: UIApplication) {
107    self.configureSdk()
108  }
109}

If your app uses version 8 or 9 of the SDK, use this code.

SDK for iOS, version 8 or 9
1import SFMCSDK
2import MarketingCloudSDK
3
4class AppDelegate: UIResponder, UIApplicationDelegate {
5
6  var window: UIWindow?
7
8  // SDK: REQUIRED IMPLEMENTATION
9
10  // The appID, accessToken and appEndpoint are required values for MobilePush SDK Module configuration and are obtained from your MobilePush app.
11  // See https://salesforce-marketingcloud.github.io/MarketingCloudSDK-iOS/get-started/get-started-setupapps.html for more information.
12  #if DEBUG
13    let appId = "[DEV-APNS App ID value from MobilePush app admin]"
14    let accessToken = "[DEV-APNS Access Token value from MobilePush app admin]"
15    let appEndpoint = "[DEV-APNS App Endpoint value from MobilePush app admin]"
16    let mid = "[DEV-APNS account MID value from MobilePush app admin]"
17  #else
18    let appId = "[PROD-APNS appId value from MobilePush app admin]"
19    let accessToken = "[PROD-APNS accessToken value from MobilePush app admin]"
20    let appEndpoint = "[PROD-APNS app endpoint value from MobilePush app admin]"
21    let mid = "[PROD-APNS account MID value from MobilePush app admin]"
22  #endif
23
24
25  // Define features of MobilePush your app will use.
26  let inbox = false
27  let location = false
28  let analytics = true
29
30  // SDK: REQUIRED IMPLEMENTATION
31  func configureSDK() {
32    // Enable logging for debugging early on. Debug level is not recommended for production apps, as significant data
33    // about the MobilePush will be logged to the console.
34    #if DEBUG
35    SFMCSdk.setLogger(logLevel: .debug)
36    #endif
37
38    // Use the Mobile Push Config Builder to configure the Mobile Push Module. This gives you the maximum flexibility in SDK configuration.
39    // The builder lets you configure the module parameters at runtime.
40    let mobilePushConfiguration = PushConfigBuilder(appId: appId)
41      .setAccessToken(accessToken)
42      .setMarketingCloudServerUrl(appEndpoint)
43      .setMid(mid)
44      .setInboxEnabled(inbox)
45      .setLocationEnabled(location)
46      .setAnalyticsEnabled(analytics)
47      .build()
48
49    // Set the completion handler to take action when module initialization is completed. The result indicates if initialization was sucesfull or not.
50    // Seting the completion handler is optional.
51    let completionHandler: (OperationResult) -> () = { result in
52      if result == .success {
53        // module is fully configured and ready for use
54      } else if result == .error {
55        // module failed to initialize, check logs for more details
56      } else if result == .cancelled {
57        // module initialization was cancelled (for example due to re-confirguration triggered before init was completed)
58      } else if result == .timeout {
59        // module failed to initialize due to timeout, check logs for more details
60      }
61    }
62
63    // Once you've created the mobile push configuration, intialize the SDK.
64    SFMCSdk.initializeSdk(ConfigBuilder().setPush(config: mobilePushConfiguration, onCompletion: completionHandler).build())
65  }
66
67  // SDK: REQUIRED IMPLEMENTATION
68  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
69    self.configureSDK()
70
71    return true
72  }
73
74  // SDK: OPTIONAL IMPLEMENTATION (if using Data Protection)
75  func applicationProtectedDataDidBecomeAvailable(_ application: UIApplication) {
76    if (SFMCSdk.mp.getStatus() != .operational) {
77      self.configureSFMCSdk()
78    }
79  }
80}

If your app uses version 7 of the SDK, use this code.

SDK for iOS, version 7
1import MarketingCloudSDK
2
3class AppDelegate: UIResponder, UIApplicationDelegate {
4
5  var window: UIWindow?
6
7  // MobilePush SDK: REQUIRED IMPLEMENTATION
8
9  // The appID, accessToken and appEndpoint are required values for MobilePush SDK configuration and are obtained from your MobilePush app.
10  // See https://salesforce-marketingcloud.github.io/MarketingCloudSDK-iOS/get-started/get-started-setupapps.html for more information.
11
12  // Use the builder method to configure the SDK for usage. This gives you the maximum flexibility in SDK configuration.
13  // The builder lets you configure the SDK parameters at runtime.
14  #if DEBUG
15
16  let appID = "[DEV-APNS App ID value from MobilePush app admin]"
17  let accessToken = "[DEV-APNS Access Token value from MobilePush app admin]"
18  let appEndpoint = "[DEV-APNS App Endpoint value from MobilePush app admin]"
19  let mid = "[DEV-APNS account MID value from MobilePush app admin]"
20  #else
21  let appId = "[PROD-APNS appId value from MobilePush app admin]"
22  let accessToken = "[PROD-APNS accessToken value from MobilePush app admin]"
23  let appEndpoint = "[PROD-APNS app endpoint value from MobilePush app admin]"
24  let mid = "[PROD-APNS account MID value from MobilePush app admin]"
25  #endif
26
27
28  // Define features of MobilePush your app will use.
29  let inbox = false
30  let location = false
31  let analytics = true
32
33  // MobilePush SDK: REQUIRED IMPLEMENTATION
34  @discardableResult
35  func configureMarketingCloudSDK() -> Bool {
36    // Use the builder method to configure the SDK for usage. This gives you the maximum flexibility in SDK configuration.
37    // The builder lets you configure the SDK parameters at runtime.
38    let builder = MarketingCloudSDKConfigBuilder()
39      .sfmc_setApplicationId(appID)
40      .sfmc_setAccessToken(accessToken)
41      .sfmc_setMarketingCloudServerUrl(appEndpoint)
42      .sfmc_setMid(mid)
43      .sfmc_setInboxEnabled(inbox as NSNumber)
44      .sfmc_setLocationEnabled(location as NSNumber)
45      .sfmc_setAnalyticsEnabled(analytics as NSNumber)
46      .sfmc_build()!
47
48    var success = false
49
50    // Once you've created the builder, pass it to the sfmc_configure method.
51    do {
52      try MarketingCloudSDK.sharedInstance().sfmc_configure(with:builder)
53      success = true
54    } catch let error as NSError {
55      // Errors returned from configuration will be in the NSError parameter and can be used to determine
56      // if you've implemented the SDK correctly.
57
58      let configErrorString = String(format: "MarketingCloudSDK sfmc_configure failed with error = %@", error)
59      print(configErrorString)
60    }
61
62    if success == true {
63      // The SDK has been fully configured and is ready for use!
64
65      // Enable logging for debugging. Not recommended for production apps, as significant data
66      // about MobilePush will be logged to the console.
67      #if DEBUG
68      MarketingCloudSDK.sharedInstance().sfmc_setDebugLoggingEnabled(true)
69      #endif
70    }
71
72    return success
73  }
74
75  // MobilePush SDK: REQUIRED IMPLEMENTATION
76  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
77    return self.configureMarketingCloudSDK()
78  }
79
80  // MobilePush SDK: OPTIONAL IMPLEMENTATION (if using Data Protection)
81  func applicationProtectedDataDidBecomeAvailable(_ application: UIApplication) {
82    if(MarketingCloudSDK.sharedInstance().sfmc_isReady() == false)
83    {
84      self.configureMarketingCloudSDK()
85    }
86  }
87}

Enable or disable analytics, location, or inbox entries depending on the application’s needs and your usage of Marketing Cloud Engagement.

iOS Data Protection affects the SDK as described in this table.

iOS Data Protection LevelSDK Behavior
No protectionSDK works in the foreground and background
Complete until first user authenticationSDK works in the foreground and background after first unlock
Complete unless openSDK works in the foreground and background after first unlock
CompleteSDK works only in the foreground after the device is unlocked

Enable Push Notifications 

Before you enable push notifications, provision your app for push notifications.

  1. Enable push notifications in your target’s Capabilities settings.

  2. Set your AppDelegate class to adhere to the UIApplicationDelegate and UNUserNotificationCenterDelegate protocol.

    1class AppDelegate: UIApplicationDelegate, UNUserNotificationCenterDelegate
    2...
  3. Extend the SDK configuration code outlined in Configure the SDK to add support for push registration.

    If your app uses version 10 or higher of the SDK, use this code.

    SDK for iOS, version 10 or higher
    1// MobilePush SDK: REQUIRED IMPLEMENTATION
    2 func configureSdk() -> Bool {
    3
    4   // Enable logging for debugging early on. Debug level is not recommended for production apps, as significant data
    5   // about the SDK will be logged to the console.
    6   #if DEBUG
    7     SFMCSdk.setLogger(logLevel: .debug)
    8   #endif
    9
    10   // Use the `PushFeatureConfigBuilder` to configure the Push Feature SDK. This gives you the maximum flexibility in SDK configuration.
    11   // The builder lets you configure the module parameters at runtime.
    12
    13   let pushFeatureConfiguration = PushFeatureConfigBuilder()
    14     .setApplicationControlsBadging(true)
    15     .build()
    16
    17   // Set the completion handler to take action when all modules initialization is completed.
    18   // Seting the completion handler is optional.
    19
    20   let completionHandler: ((_ status: [ModuleInitStatus]) -> Void) = { [weak self] status in
    21     DispatchQueue.main.async {
    22       self?.handleSDKInitializationCompletion(status: status)
    23     }
    24   }
    25
    26   SFMCSdk.initializeSdk(ConfigBuilder().setMAM(
    27     config: pushFeatureConfiguration).build(),
    28     completion: completionHandler
    29   )
    30
    31   return true
    32 }
    33
    34 // MARK: - SDK Initialization Completion Handler
    35
    36 private func handleSDKInitializationCompletion(status: [ModuleInitStatus]) {
    37   var allSuccessful = true
    38
    39   for moduleStatus in status {
    40     print("Module: \(moduleStatus.moduleName.rawValue), Status: \(moduleStatus.initStatus.rawValue)")
    41
    42     if moduleStatus.initStatus == .success {
    43       // Handle successful initialization for each module
    44       switch moduleStatus.moduleName {
    45       case .pushFeature:
    46         setupPushFeature()
    47       default:
    48         break
    49       }
    50     } else if moduleStatus.initStatus == .error {
    51       allSuccessful = false
    52       // module failed to initialize, check logs for more details
    53     } else if moduleStatus.initStatus == .cancelled {
    54       allSuccessful = false
    55       // module initialization was cancelled (for example if the
    56       // re-configuration was triggered before initialization completed)
    57     } else if moduleStatus.initStatus == .timeout {
    58       allSuccessful = false
    59       // module failed to initialize due to timeout, check logs for more details
    60     }
    61   }
    62   if allSuccessful {
    63     print("SDK initialization completed successfully")
    64   } else {
    65     print("SDK initialization completed with errors - check logs above")
    66   }
    67 }
    68
    69 func setupPushFeature() {
    70   // Set the URLHandlingDelegate to handle URLs from CloudPage, OpenDirect,
    71   //Location, and Inbox messages. In this example, the AppDelegate class adheres
    72   // to the URLHandlingDelegate protocol (see below).
    73   PushFeature.requestSdk { pushFeature in
    74     DispatchQueue.main.async {
    75       pushFeature?.setURLHandlingDelegate(self)
    76     }
    77   }
    78 }
    79
    80 func application(
    81   _ application: UIApplication,
    82   didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    83 ) -> Bool {
    84   self.configureSdk()
    85   return true
    86 }

    If your app uses version 8 or 9 of the SDK, use this code.

    SDK for iOS, version 8 and 9
    1// SDK: REQUIRED IMPLEMENTATION
    2 func configureSDK() {
    3   #if DEBUG
    4     SFMCSdk.setLogger(logLevel: .debug)
    5   #endif
    6
    7   let mobilePushConfiguration = PushConfigBuilder(appId: appId)
    8     .setAccessToken(accessToken)
    9     .setMarketingCloudServerUrl(appEndpoint)
    10     .setMid(mid)
    11     .setInboxEnabled(inbox)
    12     .setLocationEnabled(location)
    13     .setAnalyticsEnabled(analytics)
    14     .build()
    15
    16   let completionHandler: (OperationResult) -> () = { result in
    17     if result == .success {
    18       self.setupMobilePush()
    19     }
    20   }
    21
    22   SFMCSdk.initializeSdk(ConfigBuilder().setPush(config: mobilePushConfiguration, onCompletion: completionHandler).build())
    23 }
    24
    25 func setupMobilePush() {
    26
    27   // Set the MarketingCloudSDKURLHandlingDelegate to a class adhering to the protocol.
    28   // In this example, the AppDelegate class adheres to the protocol (see below)
    29   // and handles URLs passed back from the SDK.
    30   // For more information, see https://salesforce-marketingcloud.github.io/MarketingCloudSDK-iOS/sdk-implementation/implementation-urlhandling.html
    31   SFMCSdk.requestPushSdk { mp in
    32     mp.setURLHandlingDelegate(self)
    33   }
    34
    35   // Make sure to dispatch this to the main thread, as UNUserNotificationCenter will present UI.
    36   DispatchQueue.main.async {
    37     // Set the UNUserNotificationCenterDelegate to a class adhering to thie protocol.
    38     // In this exmple, the AppDelegate class adheres to the protocol (see below)
    39     // and handles Notification Center delegate methods from iOS.
    40     UNUserNotificationCenter.current().delegate = self
    41
    42       // Request authorization from the user for push notification alerts.
    43       UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge], completionHandler: {(_ granted: Bool, _ error: Error?) -> Void in
    44         if error == nil {
    45           if granted == true {
    46             // Your application may want to do something specific if the user has granted authorization
    47             // for the notification types specified; it would be done here.
    48           }
    49         }
    50       })
    51
    52       // In any case, your application should register for remote notifications *each time*
    53       // your application launches to ensure that the push token used by MobilePush (for silent push)
    54       // is updated if necessary.
    55
    56       // Registering in this manner does *not* mean that a user will see a notification - it only means
    57       // that the application will receive a unique push token from iOS.
    58       UIApplication.shared.registerForRemoteNotifications()
    59   }
    60 }

    This code example shows how to configure the version 7 of the SDK for iOS apps.

    SDK for iOS, version 7
    1func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    2
    3    // ... SDK configuration setup
    4
    5    var success = false
    6
    7    do {
    8        try MarketingCloudSDK.sharedInstance().sfmc_configure(with:builder)
    9        success = true
    10    } catch let error as NSError {
    11        // Errors returned from configuration will be in the NSError parameter and can be used to determine
    12        // if you've implemented the SDK correctly.
    13
    14        let configErrorString = String(format: "MarketingCloudSDK sfmc_configure failed with error = %@", error)
    15        print(configErrorString)
    16    }
    17
    18    if success == true {
    19        // The SDK has been fully configured and is ready for use!
    20
    21        // Enable logging for debugging. Not recommended for production apps, as significant data
    22        // about MobilePush will be logged to the console.
    23        #if DEBUG
    24        MarketingCloudSDK.sharedInstance().sfmc_setDebugLoggingEnabled(true)
    25        #endif
    26
    27        // Set the MarketingCloudSDKURLHandlingDelegate to a class adhering to the protocol.
    28        // In this example, the AppDelegate class adheres to the protocol
    29        // and handles URLs passed back from the SDK.
    30        // For more information, see https://salesforce-marketingcloud.github.io/MarketingCloudSDK-iOS/sdk-implementation/implementation-urlhandling.html
    31        MarketingCloudSDK.sharedInstance().sfmc_setURLHandlingDelegate(self)
    32
    33        // Make sure to dispatch this to the main thread, as UNUserNotificationCenter will present UI.
    34        DispatchQueue.main.async {
    35            if #available(iOS 10.0, *) {
    36                // Set the UNUserNotificationCenterDelegate to a class adhering to thie protocol.
    37                // In this exmple, the AppDelegate class adheres to the protocol (see below)
    38                // and handles Notification Center delegate methods from iOS.
    39                UNUserNotificationCenter.current().delegate = self
    40
    41                // Request authorization from the user for push notification alerts.
    42                UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge], completionHandler: {(_ granted: Bool, _ error: Error?) -> Void in
    43                    if error == nil {
    44                        if granted == true {
    45                            // Your application may want to do something specific
    46                            // if the user has granted authorization for the
    47                            // notification types specified; it would be done here.
    48                            print(MarketingCloudSDK.sharedInstance().sfmc_deviceToken() ?? "error: no token - was UIApplication.shared.registerForRemoteNotifications() called?")
    49                        }
    50                    }
    51                })
    52            }
    53
    54            // In any case, your application should register for remote notifications *each time*
    55            // your application launches to ensure that the push token used by MobilePush (for silent push) is updated if necessary.
    56
    57            // Registering in this manner does *not* mean that a user will see a notification,
    58            // it only means that the application will receive a unique push token from iOS.
    59            UIApplication.shared.registerForRemoteNotifications()
    60        }
    61    }
    62
    63    return true
    64}
  4. Add the required UIApplicationDelegate protocol methods to support push registration to your AppDelegate class. This code example shows how to configure the version 8 and later of the SDK for iOS apps.

    If your app uses version 10 or higher of the SDK, use this code.

    SDK for iOS, version 10 or higher
    1// PushFeature SDK: REQUIRED IMPLEMENTATION
    2func application(_ application: UIApplication,
    3  didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    4  PushFeature.requestSdk { pushFeature in
    5    pushFeature?.setDeviceToken(deviceToken)
    6  }
    7}
    8
    9// PushFeature SDK: REQUIRED IMPLEMENTATION
    10func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
    11  print(error)
    12}
    13
    14// PushFeature SDK: REQUIRED IMPLEMENTATION
    15/**
    16This delegate method lets apps with the "remote-notification" background mode
    17fetch data in response to an incoming remote notification.
    18
    19Call the fetchCompletionHandler as soon as you're finished performing that
    20operation so the system can accurately estimate its power and data cost.
    21
    22This method is invoked even if the application was launched or resumed because
    23of the remote notification. The delegate methods are invoked first.
    24
    25This behavior is in contrast to `application(_:didReceiveRemoteNotification:)`,
    26which isn't called in those cases, and isn't invoked if this method is implemented.
    27**/
    28func application(
    29  _ application: UIApplication,
    30  didReceiveRemoteNotification userInfo: [AnyHashable : Any],
    31  fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    32    PushFeature.requestSdk { pushFeature in
    33      pushFeature?.setNotificationUserInfo(userInfo)
    34    }
    35  completionHandler(.newData)
    36}

    If your app uses version 8 or 9 of the SDK, use this code.

    SDK for iOS, version 8 or 9
    1// MobilePush SDK: REQUIRED IMPLEMENTATION
    2    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    3        SFMCSdk.requestPushSdk { mp in
    4            mp.setDeviceToken(deviceToken)
    5        }
    6    }
    7
    8    // MobilePush SDK: REQUIRED IMPLEMENTATION
    9    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
    10        print(error)
    11    }
    12
    13    // MobilePush SDK: REQUIRED IMPLEMENTATION
    14    /** This delegate method offers an opportunity for applications with the "remote-notification" background mode to fetch appropriate new data in response to an incoming remote notification.
    15    //You should call the fetchCompletionHandler as soon as you’re finished performing that operation,
    16    // so the system can accurately estimate its power and data cost.
    17    // This method will be invoked even if the application was launched or resumed because of the remote notification.
    18    // The respective delegate methods will be invoked first.
    19    // Note that this behavior is in contrast to application:didReceiveRemoteNotification:, which is not called in those cases, and which will not be invoked if this method is implemented. **/
    20    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    21        SFMCSdk.requestPushSdk { mp in
    22            mp.setNotificationUserInfo(userInfo)
    23        }
    24        completionHandler(.newData)
    25    }

    This code example shows how to configure the version 7 and earlier of the SDK for iOS apps.

    SDK for iOS, version 7
    1// MobilePush SDK: REQUIRED IMPLEMENTATION
    2    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    3        MarketingCloudSDK.sharedInstance().sfmc_setDeviceToken(deviceToken)
    4    }
    5
    6    // MobilePush SDK: REQUIRED IMPLEMENTATION
    7    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
    8        print(error)
    9    }
    10
    11    // MobilePush SDK: REQUIRED IMPLEMENTATION
    12    /** This delegate method offers an opportunity for applications with the "remote-notification" background mode to fetch appropriate new data in response to an incoming remote notification.
    13    //You should call the fetchCompletionHandler as soon as you’re finished performing that operation, so the system can accurately estimate its power and data cost.
    14    // This method will be invoked even if the application was launched or resumed because of the remote notification.
    15    // The respective delegate methods will be invoked first. Note that this behavior is in contrast to application:didReceiveRemoteNotification:, which is not called in those cases, and which will not be invoked if this method is implemented. **/
    16    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    17        MarketingCloudSDK.sharedInstance().sfmc_setNotificationUserInfo(userInfo)
    18        completionHandler(.newData)
    19    }
  5. Add the required UNUserNotificationCenterDelegate protocol methods to support push notifications to your AppDelegate class.

    If your app uses version 10 or higher of the SDK, use this code.

    SDK for iOS, version 10 or higher
    1/// The method is called on the delegate when the user responds to the notification
    2 /// by opening the application, dismissing the notification or choosing a
    3 /// UNNotificationAction. The delegate must be set before the application returns
    4 /// from applicationDidFinishLaunching:.
    5 /// *
    6 func userNotificationCenter(
    7 _ center: UNUserNotificationCenter,
    8 didReceive response: UNNotificationResponse,
    9 withCompletionHandler completionHandler: @escaping () -> Void
    10 ) {
    11 // Required: Tell theSDK about the notification so that it begins to
    12 // collect analytics and process the notification for your app.
    13 PushFeature.requestSdk { pushFeature in
    14     pushFeature?.setNotificationResponse(response)
    15 }
    16 completionHandler()
    17 }
    18
    19 /// The method is called on the delegate only if the application is in the
    20 /// foreground. If the method isn't implemented or the handler isn't called in a
    21 /// timely manner, then the notification isn't shown. The application can
    22 /// have the notification presented as a sound, badge, alert, or it can appear
    23 /// in the notification list. This decision should be based on whether the
    24 /// information in the notification is otherwise visible to the user.
    25 /// *
    26 func userNotificationCenter(
    27 _ center: UNUserNotificationCenter,
    28 willPresent notification: UNNotification,
    29 withCompletionHandler completionHandler: @escaping (
    30     UNNotificationPresentationOptions
    31 ) -> Void
    32 ) {
    33 completionHandler(.alert)
    34 }

    If your app uses version 9 of the SDK, use this code.

    SDK for iOS, version 9
    1// MobilePush SDK: REQUIRED IMPLEMENTATION
    2// The method will be called on the delegate when the user responded to the notification by opening the application,
    3// dismissing the notification or choosing a UNNotificationAction.
    4// The delegate must be set before the application returns from applicationDidFinishLaunching:.
    5@available(iOS 10.0, *)
    6func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    7    // Required: tell the MarketingCloudSDK about the notification. This will collect MobilePush analytics
    8    // and process the notification on behalf of your application.
    9    SFMCSdk.requestPushSdk { mp in
    10        mp.setNotificationResponse(response)
    11    }
    12    completionHandler()
    13}
    14
    15// MobilePush SDK: REQUIRED IMPLEMENTATION
    16// The method will be called on the delegate only if the application is in the foreground.
    17// If the method is not implemented or the handler is not called in a timely manner then the notification will not be presented.
    18// The application can choose to have the notification presented as a sound, badge, alert and/or in the notification list.
    19// This decision should be based on whether the information in the notification is otherwise visible to the user.
    20@available(iOS 10.0, *)
    21func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    22    completionHandler(.alert)
    23}

    If your app uses version 8 of the SDK, use this code.

    SDK for iOS, version 8
    1// MobilePush SDK: REQUIRED IMPLEMENTATION
    2// The method will be called on the delegate when the user responded to the notification by opening the application,
    3// dismissing the notification or choosing a UNNotificationAction.
    4// The delegate must be set before the application returns from applicationDidFinishLaunching:.
    5@available(iOS 10.0, *)
    6func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    7    // Required: tell the MarketingCloudSDK about the notification. This will collect MobilePush analytics
    8    // and process the notification on behalf of your application.
    9    SFMCSdk.requestPushSdk { mp in
    10        mp.setNotificationRequest(response.notification.request)
    11    }
    12    completionHandler()
    13}
    14
    15// MobilePush SDK: REQUIRED IMPLEMENTATION
    16// The method will be called on the delegate only if the application is in the foreground.
    17// If the method is not implemented or the handler is not called in a timely manner then the notification will not be presented.
    18// The application can choose to have the notification presented as a sound, badge, alert and/or in the notification list.
    19// This decision should be based on whether the information in the notification is otherwise visible to the user.
    20@available(iOS 10.0, *)
    21func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    22    completionHandler(.alert)
    23}

    If your app uses version 7 of the SDK, use this code.

    SDK for iOS, version 7
    1// MobilePush SDK: REQUIRED IMPLEMENTATION
    2// The method will be called on the delegate when the user responded to the notification by opening the application,
    3// dismissing the notification or choosing a UNNotificationAction.
    4// The delegate must be set before the application returns from applicationDidFinishLaunching:.
    5@available(iOS 10.0, *)
    6func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    7    // Required: Tell MarketingCloudSDK about the notification.
    8    // This will collect MobilePush analytics and process the notification on behalf of your application.
    9    MarketingCloudSDK.sharedInstance().sfmc_setNotificationRequest(response.notification.request)
    10    completionHandler()
    11}
    12
    13// MobilePush SDK: REQUIRED IMPLEMENTATION
    14// The method will be called on the delegate only if the application is in the foreground.
    15// If the method is not implemented or the handler is not called in a timely manner then the notification will not be presented.
    16// The application can choose to have the notification presented as a sound, badge, alert and/or in the notification list.
    17// This decision should be based on whether the information in the notification is otherwise visible to the user.
    18@available(iOS 10.0, *)
    19func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    20    completionHandler(.alert)
    21}

    The methods described in this procedure use MarketingCloud SDK APIs to facilitate the framework’s functionality to manage push notifications, which include contact registration and push analytics tracking. If you implement the methods without using the MarketingCloud SDK methods, these features don’t work as expected.

    Note