Migrate to the Next-Gen MobilePush SDK for iOS

The MobilePush SDK version 8.x update sets a more modern architectural foundation to enable a variety of improvements and all new features for future versions. The updated MobilePush SDK is designed with existing MobilePush customers in mind so that the upgrade path is light and straightforward.

To migrate to MobilePush SDK version 8 or later, follow these steps.

Add the New iOS SDK Build 

  1. Remove the existing CocoaPods dependency before adding MarketingCloudSDK from Swift Package Manager (MobilePush).
  2. Add the MobilePush dependency (tag 8.x) to your application target.

If you use version 8.0.13 or earlier of the SDK, add the SFMCSDK (tag 1.x) and MobilePush (tag 8.x) dependencies to your application target.

Manually pull the Resources/MarketingCloudSDK.bundle from the sources folder in the MarketingCloudSDK Swift module and add it as a resource within Copy Bundle Resources in the build phase configuration. If you don’t complete this step, you’ll encounter this error: Thread 1: Cannot create an NSPersistentStoreCoordinator with a nil model.

Initialize the SDK 

You must replace your existing initialization function to reference the new SDK. After you’ve fetched the updated SDK version in your project, the functions that must be modified are highlighted in your codebase.

  1. Update the configuration builder function as shown in this example.

  2. Ensure that the SDK has initialized correctly by using a check on the status of initialization or by using the completion handler, as shown in this example.

    1// Old
    2
    3let builder = MarketingCloudSDKConfigBuilder()
    4            .sfmc_setApplicationId(appID)
    5            .sfmc_setAccessToken(accessToken)
    6            .sfmc_setMarketingCloudServerUrl(appEndpoint)
    7            .sfmc_build()!
    8
    9var success = false
    10
    11do {
    12    try MarketingCloudSDK.sharedInstance().sfmc_configure(with:builder)
    13    success = true
    14} catch let error as NSError {
    15    // error logic
    16}
    17
    18if success == true {
    19    //function logic
    20}
    21
    22// New
    23
    24// With manual check on the module initialization success
    25let configuration = PushConfigBuilder(appId: PUSH_APP_ID)
    26    .setAccessToken(PUSH_ACCESS_TOKEN)
    27    .setMarketingCloudServerUrl(URL(string: PUSH_TSE)!)
    28    .build()
    29
    30SFMCSdk.initializeSdk(ConfigBuilder().setPush(config: configuration).build())
    31
    32if SFMCSdk.mp.getStatus() == .operational {
    33    //function logic
    34}
    35
    36// Or with using the completion handler
    37let configuration = PushConfigBuilder(appId: PUSH_APP_ID)
    38    .setAccessToken(PUSH_ACCESS_TOKEN)
    39    .setMarketingCloudServerUrl(URL(string: PUSH_TSE)!)
    40    .build()
    41
    42SFMCSdk.initializeSdk(ConfigBuilder()
    43    .setPush(
    44          config: configuration,
    45          onCompletion: {result in print("TODO, Module initialization result is: \(result.rawValue)")}
    46    ).build())

Update Identity Functions 

  1. Set the identity or ID of a known user: Replace your current identity tracking function setContactKey with the updated function setProfileID.

  2. Set the Attributes of a user: Replace your existing identity tracking function setAttribute with the updated function setProfileAttributes.

    1// Old
    2MarketingCloudSDK.sharedInstance().sfmc_setContactKey("john.smith")
    3
    4// New
    5SFMCSdk.identity.setProfileId("john.smith")

Update Remaining Functions 

Align your existing functions with updated functions provided by the new SDK. All existing functions that need changes are marked as deprecated in your codebase.

Capture Notifications On Launch (Only for 8.0.x) 

If you’re using version 8.1.x of the SDK, you don’t need to perform this step. Using the new requestPushSdk API enables the SDK to automatically capture notifications for you, regardless of the application’s state and the SDK initialization status. For a complete implementation example, see the iOS LearningApp.

Note

To ensure push notifications are processed accurately when your application isn’t actively running, capture them during application launch and store them in memory until the SDK initializes fully. Failing to do so prevents the SDK from processing incoming push notifications. After the SDK is operational, the notification is set to the SDK using setNotificationUserInfo API, as shown in this example.

1// Add a member variable in the AppDelegate class
2@UIApplicationMain
3class AppDelegate: UIResponder, UIApplicationDelegate {
4
5   // ...
6
7   // Notification to capture
8   var notificationUserInfo:[AnyHashable:Any]?
9
10// -----------------------------
11
12func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
13
14 // Extract the notification from launchOptions
15 if let options = launchOptions, let notification = options[UIApplication.LaunchOptionsKey.remoteNotification] as? [AnyHashable: Any] {
16   self.notificationUserInfo = notification
17 }
18 // ...
19
20 let completionHandler: (OperationResult) -> () = { result in
21   if result == .success {
22     // Method to call when the SDK is ready
23     self.setupMobilePush()
24   }
25 }
26
27 // Initialize the SDK
28 SFMCSdk.initializeSdk(
29   ConfigBuilder().setPush(
30       config: mobilePushConfiguration,
31       onCompletion: completionHandler
32   ).build()
33 )
34
35 // ...
36}
37
38// -----------------------------
39
40func setupMobilePush() {
41 // ...
42
43 // Provide the notification object to SDK when the SDK is ready.
44 DispatchQueue.main.async {
45   if let userInfo = self.notificationUserInfo {
46     SFMCSdk.mp.setNotificationUserInfo(userInfo)
47   } else {
48     debugPrint("No notification UserInfo: - either it should be a direct launch or Notification userInfo is not available when launched from notification")
49   }
50 }
51}
52}

For a complete implementation example, see the iOS LearningApp.