Cannot handle OpenDirect push notification when iOS app is not launched

iosmarketing-cloudmobilepushmobilepush-iosnotification

Thank you for creating versatile push notification solution and recent update of SDK v8 was much Swifty API😄

I have a problem handling OpenDirect push notifications when the app is not launched.

I read Enable Push and follow implementation but UNUserNotificationCenterDelegate.userNotificationCenter(_:didReceive:withCompletionHandler:) not called when open push notification in app not launched.

Problem was setting SFMCSdk.mp.setURLHandlingDelegate(self) and UNUserNotificationCenterDelegate in completion handler called after application did finish launch, because SFMCSdk.initializeSdk(ConfigBuilder().setPush(config: mobilePushConfiguration, onCompletion: completionHandler).build())'s completionHandler call in async.

Apple document says you need to set UNUserNotificationCenterDelegate before your app finishes launching.

UNUserNotificationCenterDelegate | Apple Developer Documentation

You must assign your delegate object to the UNUserNotificationCenter object before your app finishes launching. For example, in an iOS app, you must assign it in the application(:willFinishLaunchingWithOptions:) or application(:didFinishLaunchingWithOptions:) method of your app delegate. Assigning a delegate after the system calls these methods might cause you to miss incoming notifications.

Also, I tried to implement AppDelegate.application(_:didReceiveRemoteNotification:fetchCompletionHandler:) followed by your document, but MarketingCloud SDK logged `Module is not initialized. You need to initialize before using. Current status: initializing.

/ MobilePush SDK: REQUIRED IMPLEMENTATION
** 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. 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.
This method will be invoked even if the application was launched or resumed because of the remote notification. 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. **/
unc application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
SFMCSdk.mp.setNotificationUserInfo(userInfo)
completionHandler(.newData)

Enviroment

MarketingCloud SDK v8.0.6
iOS 15.5

Is there something I missed?

Thank you for your support.

Best Answer

SFMCSdk.mp.setURLHandlingDelegate(self) should be set only after successful initialization of the SDK.

For opendirect, when app is not in launched state, the SDK instance will be lost and hence when you launch the app the SDK starts initializing again along with the other application lifecycle events and hence SDK get into "Initializing" state.

Hence, The notification object should be held in the application in memory variable when the app is launched through remote notification and set it to the marketingCloudSDK after the SDK's operational status is "Operational" using SDK's method below:

SFMCSdk.mp.setNotificationRequest(notificationRequest). 

Note: If in SceneDelegate, may have to handle it in below function as

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
     if let response = connectionOptions.notificationResponse {
                   
        self.notificationRequest = response.notification.request
       }
 }

if in Appdelegate, should be handled in

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool 
{
 }

Hope this helps!

Thanks, Prakashini

Related Topic