iOS Push Notifications - SDK 4.0.0

Leanplum iOS SDK 4.0.0 brings changes to how Push Notifications are handled. We have improved the automatic push setup through swizzling as well as the public methods that should be used when swizzling is disabled.

Swizzling Enabled

If the automatic swizzling is enabled, there are no changes to be made.

📘

Ensure Leanplum Start is called from your AppDelegate didFinishLaunchingWithOptions as shown in the SDK Integration docs. This enables swizzling to work smoothly when app is woken up in the background or app is started from opening a push notification.

If you use swizzling but also use custom UNUserNotificationCenterDelegate, you must set the delegate to the current center before calling Leanplum Start.

Internal Swizzling Changes

The below information covers implementation specifics and aims to provide additional information for App Developers.

Swizzling now behaves based on the device OS version. This way we can rely on the UNUserNotificationCenter for iOS 10 and above.

Leanplum implements and sets the UNUserNotificationCenterDelegate to the AppDelegate if the client app has not implemented it, otherwise it swizzles the methods. Since methods are optional, we do fallback so the client app can still get notified.

Details

If userNotificationCenter:didReceive:withCompletionHandler: is called and the client app has not implemented it, but has a UNUserNotificationCenterDelegate set, we fallback to application:didReceiveRemoteNotification:fetchCompletionHandler: so client app can still handle the notification open.

if application:didReceiveRemoteNotification:fetchCompletionHandler: is called and client app has not implemented it, but relies on the deprecated application:didReceiveRemoteNotification, we do fallback and call the latter.

Methods

Methods used iOS 10, *:

  • application:didFinishLaunchingWithOptions (NotificationCenter observer didFinishLaunchingNotification)
  • application:didReceiveRemoteNotification:fetchCompletionHandler: (used for prefetch when background mode - remote notifications is enabled)
  • userNotificationCenter:willPresent:withCompletionHandler: (also used for local notifications)
  • userNotificationCenter:didReceive:withCompletionHandler:

Methods used iOS 9:

  • application:didFinishLaunchingWithOptions (NotificationCenter observer didFinishLaunchingNotification)
  • application:didReceiveRemoteNotification:fetchCompletionHandler: (used for prefetch, receive and open/tap)
  • application:didReceive: (for local notifications)

Swizzling Disabled

If you have disabled swizzling and call Leanplum methods manually, there are breaking changes you need to conform to.

Methods

Leanplum listens for the applicationDidFinishLaunching so now you must call the following method from your application:didFinishLaunchingWithOptions:

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

📘

Note that for all methods you must call the completionHandler yourself.

func application(_ application: UIApplication,
 didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { 
  Leanplum.didReceiveRemoteNotification(userInfo)
  completionHandler(.newData)
}

For iOS 10 and above, implement the UNUserNotificationCenter:

@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter,
 didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    Leanplum.didReceive(response)
    completionHandler()
}

@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter,
  willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    Leanplum.willPresent(notification)
    completionHandler([])
}

Notification Settings / Push Types

Leanplum now tracks the following push types - badge, sound, alert, notification center, lock screen, provisional, and time-sensitive.

Push Delivery

Push Delivery is now tracked automatically. A global Push Delivered event is tracked for each notification. In order for the tracking to be accurate, you need to enable Background Modes: Remote Notifications capability for your app. This way the app will be woken up by iOS when a notification is received if the app was not running.

Note that if the app is fully suspended by the user, iOS does not inform the app in any way when a notification arrives, so tracking of the delivery is not possible in this situation. The notification will be displayed and opening it, will work as expected.

Push Enabling

You can now enable notifications the following way:

Leanplum.enablePushNotifications() // enables .alert, .badge, .sound
Leanplum.enableProvisionalPushNotifications() // enables provisional only

Both methods call UIApplication.shared.registerForRemoteNotifications().

Presentation Options

You can now change the presentation options for notifications when they are received while the app is in the foreground.

For example:

Leanplum.setPushNotificationPresentationOption([.badge, .alert])

This will present the notifications as an alert.

To prevent the default behavior of showing an in-app confirm at the same time, set the delegate:

Leanplum.setShouldOpenNotificationHandler { notificaiton, lpBlock in    
}