Troubleshoot Multiple Push SDKs with Swizzling Enabled
If Swizzling is enabled, implement the other push provider’s delegate methods first. When that’s complete, implement the Salesforce Engagement SDK methods.
Configure the SDK along with the other Push provider, as shown in these code examples.
Code example for iOS SDK v10 or later:
1func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) ->Bool{2 if let options = launchOptions, let notification = options[UIApplication.LaunchOptionsKey.remoteNotification] as? [AnyHashable: Any]{3 self.notificationUserInfo = notification4}56 FirebaseApp.configure()7 Messaging.messaging().delegate = self8 self.configureSdk()910 if #available(iOS 10.0, *){11 UNUserNotificationCenter.current().delegate = self1213 let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]14 UNUserNotificationCenter.current().requestAuthorization(15 options: authOptions,16 completionHandler: {_, _ in}17)18}else{19 let settings: UIUserNotificationSettings =20 UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)21 application.registerUserNotificationSettings(settings)22}23 application.registerForRemoteNotifications()2425 return true2627}2829@discardableResult30func configureSdk() ->Bool{31let appID = "<your appID here>"32let accessToken = "<your accessToken here>"33let appEndpointURL = "<your appEndpoint here>"34let mid = "<your account MID here>"3536#if DEBUG37SFMCSdk.setLogger(logLevel: .debug)38#endif3940 let appEndpoint = URL(string: appEndpointURL)!4142 var configBuilder = ConfigBuilder()4344 let engagementConfiguration = MarketingCloudSdkConfigBuilder(appId: appID)45 .setAccessToken(accessToken)46 .setMarketingCloudServerUrl(URL(string: appEndpointURL)!)47 .setMid(mid)48 .setInboxEnabled(true)49 .setLocationEnabled(true)50 .setAnalyticsEnabled(true)51 .build()5253 configBuilder = configBuilder54 .setEngagement(config: engagementConfiguration)5556 let pushFeatureConfiguration = PushFeatureConfigBuilder()57 .setApplicationControlsBadging(true)58 .build()5960 configBuilder = configBuilder61 .setPushFeature(config: pushFeatureConfiguration)6263 // Set the completion handler to take action when all modules initialization is completed.64 // Seting the completion handler is optional.6566 let completionHandler: ((_ status: [ModuleInitStatus]) ->Void) = {[weak self] status in67 DispatchQueue.main.async{68 self?.handleSDKInitializationCompletion(status: status)69}70}7172 SFMCSdk.initializeSdk(configBuilder.build(), completion: completionHandler)7374 return true7576}7778// MARK: - SDK Initialization Completion Handler7980private func handleSDKInitializationCompletion(status: [ModuleInitStatus]){81var allSuccessful = true8283 for moduleStatus in status {84 print("Module: \(moduleStatus.moduleName.rawValue), Status: \(moduleStatus.initStatus.rawValue)")8586 if moduleStatus.initStatus == .success {87 // Handle successful initialization for each module88 switch moduleStatus.moduleName {89 case .engagement:90 // Handle successful initialization for Marketing cloud module91 case .pushFeature:92 // Handle successful initialization for Push Feature module93 default:94 break95}96}else if moduleStatus.initStatus == .error{97 allSuccessful = false98 // module failed to initialize, check logs for more details99}else if moduleStatus.initStatus == .cancelled {100 allSuccessful = false101 // module initialization was cancelled (for example due to re-confirguration triggered before init was completed)102}else if moduleStatus.initStatus == .timeout {103 allSuccessful = false104 // module failed to initialize due to timeout, check logs for more details105}106}107 if allSuccessful {108 print("SDK initialization completed successfully")109}else{110 print("SDK initialization completed with errors - check logs above")111}112113}
Code example for iOS SDK v8:
1func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) ->Bool{2 if let options = launchOptions, let notification = options[UIApplication.LaunchOptionsKey.remoteNotification] as? [AnyHashable: Any]{3 self.notificationUserInfo = notification4}56 FirebaseApp.configure()7 Messaging.messaging().delegate = self8 self.configureSFMCSdk()910 if #available(iOS 10.0, *){11 UNUserNotificationCenter.current().delegate = self1213 let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]14 UNUserNotificationCenter.current().requestAuthorization(15 options: authOptions,16 completionHandler: {_, _ in}17)18}else{19 let settings: UIUserNotificationSettings =20 UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)21 application.registerUserNotificationSettings(settings)22}23 application.registerForRemoteNotifications()2425 return true26}2728@discardableResult29func configureSFMCSdk() ->Bool{30 let appID = "<your appID here>"31 let accessToken = "<your accessToken here>"32 let appEndpointURL = "<your appEndpoint here>"33 let mid = "<your account MID here>"3435#if DEBUG36 SFMCSdk.setLogger(logLevel: .debug)37#endif3839 let appEndpoint = URL(string: appEndpointURL)!4041 let mobilePushConfiguration = PushConfigBuilder(appId: appID)42 .setAccessToken(accessToken)43 .setMarketingCloudServerUrl(appEndpoint)44 .setMid(mid)45 .setInboxEnabled(true)// enable if needed by your application46 .setLocationEnabled(true)// enable if needed by your application47 .setAnalyticsEnabled(true)// enable if needed by your application48 .build()4950 let completionHandler: (OperationResult) ->() = { result in51 if result == .success {52 self.setupMobilePush()53}else if result == .error{54}else if result == .cancelled {55}else if result == .timeout {56}57}5859 SFMCSdk.initializeSdk(ConfigBuilder().setPush(config: mobilePushConfiguration, onCompletion: completionHandler).build())6061 return true
Configure the SDK to set the device token, as shown in these code examples.
Code example for iOS SDK v10 or later:
1// MARK: FireBaseMessaging Delegate2/**3Set deviceToken to MarketingCloudSDK in the FCM delegate method when Swizzling is enabled.4DeviceToken must be set MANDATORILY to MarketingCloudSDK using`SFMCSdk.mp.setDeviceToken` API for Push notifications to be received through Mobile Push.5*/6extension AppDelegate : MessagingDelegate {7 func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?){8 print("FCM Token", fcmToken ?? "")910 PushFeature.requestSdk{ pushFeature in11 print("SDK is operational")12 if let apnsToken = messaging.apnsToken {13 print("Setting APNs token in MarketingCloudSDK")14 pushFeature?.setDeviceToken(apnsToken)15}else{16 print("fcm token is null")17}18 print("SDK is not yet operational")19}20}21}
Code example for iOS SDK v8:
1// MARK: FireBaseMessaging Delegate2/**3Set deviceToken to MarketingCloudSDK in the FCM delegate method when Swizzling is enabled.4DeviceToken must be set MANDATORILY to MarketingCloudSDK using`SFMCSdk.mp.setDeviceToken` API for Push notifications to be received through Mobile Push.5*/6extension AppDelegate : MessagingDelegate {7 func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?){8 print("FCM Token", fcmToken ?? "")910 SFMCSdk.requestPushSdk{ mp in11 print("SDK is operational")12 if let apnsToken = messaging.apnsToken {13 print("Setting APNs token in MarketingCloudSDK")14 mp.setDeviceToken(apnsToken)15}else{16 print("fcm token is null")17}18 print("SDK is not yet operational")19}20}2122}
```
When Swizzling is enabled in the other push provider, respective delegate methods are intercepted. For example, when a push notification is received from Firebase, the payload received in the didReceive notification method for the UNUserNotificationCenterDelegate is altered to receive a MessagingMessageInfo object. Because the payload doesn’t match the format that the SDK expects, the message isn’t reported.
To handle this situation, implement the delegate methods described in these code examples.
Notification messages from other providers appear in the device’s notification center. However, any action on the notification message from the SDK, such as URL handling or reporting, doesn’t work.