1

I'm working on a React Native app which uses two different libraries to handle local notifications (react-native-community/push-notification-ios) and remote push notifications (Leanplum). The Leanplum SDK uses swizzling. Unfortunately, even when I disable swizzling, the recommended setup for showing foreground notifications is preventing the remote notifications from being handled correctly.

I received a piece of feedback from the support team for the remote notification SDK

your implementation here on the local level is interfering with the Leanplum swizzle. Are you able to implement the user notification delegate protocol, extending in the app delegate class? In iOS implementations this allows the two logics (LP and local) automatically and smoothly. our recommended implementation is for the AppDelegate to extend the UNUserNotificationCenterDelegate protocol, especially if you want to keep the local push implementation

Although I'm doing my best to learn Objective-C as quickly as I can, I'm not a native iOS developer, and I'm not sure how to follow this advice. I've read through many questions regarding setting up push notifications, but they all recommend the below setup, and I've not been able to find any that deal with this case of foreground notification handling interfering with another library.

How do I extend the UNUserNotificationCenterDelegate protocol in the AppDelegate to handle foreground notifications in a way that doesn't interfere with the remote notification library?

AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

  [...]
    
  // Define UNUserNotificationCenter
  UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
  center.delegate = self; // <-- interferes with the remote notification SDK
  
  [RNSplashScreen show];
  return YES;
}

  [...]

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    [RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
    // Needs to be called if swizzling is disabled in Info.plist otherwise it won’t affect SDK if swizzling is enabled.
    [Leanplum didReceiveRemoteNotification:userInfo

fetchCompletionHandler:completionHandler];
}

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
    // Needs to be called if swizzling is disabled in Info.plist otherwise it won’t affect SDK if swizzling is enabled.
    [RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
    [Leanplum didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
    [RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error];
    // Needs to be called if swizzling is disabled in Info.plist otherwise it won’t affect SDK if swizzling is enabled.
    [Leanplum didFailToRegisterForRemoteNotificationsWithError:error];
}

// Required for localNotification event
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
         withCompletionHandler:(void (^)(void))completionHandler
{
  [RNCPushNotificationIOS didReceiveNotificationResponse:response];
}

//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
  completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge);
}

Edit: The remote notification methods are copied directly from the Leanplum docs.

When I remove this code from AppDelegate.m, everything works as expected for the remote notifications. It's only when I add these pieces to present foreground notifications that I notice problems with the Leanplum remote notifications, like the open actions failing to execute.

// Define UNUserNotificationCenter
  UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
  center.delegate = self; // <-- interferes with the remote notification SDK

...

//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
  completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge);
}
Taylour
  • 43
  • 7

1 Answers1

0

I faced the same issue but I figured out some deep Leanplum code was not called anymore when deactivating swizzling.

Add this at the top of your file

#import <Leanplum/LPPushNotificationsManager.h>

Replace

-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
  completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge);
}

With this:

-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
  [[LPPushNotificationsManager sharedManager].handler willPresentNotification:notification withCompletionHandler:completionHandler];
}
jrobichaud
  • 1,272
  • 1
  • 11
  • 23