Handle incoming notifications: iOS
Beams makes it possible trigger callback code in your application when a push notification arrives on a user’s device. This can be used to respond to the arrival of the notification in your application.
∞ While your app is running or backgrounded
When a notification arrives whilst your app is running (foreground or background) you will receive a callback in your AppDelegate
:
import UIKit
import PushNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
let beamsClient = PushNotifications.shared
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
let remoteNotificationType = self.beamsClient.handleNotification(userInfo: userInfo)
if remoteNotificationType == .ShouldIgnore {
return // This was an internal-only notification from Pusher.
}
// Do something fabulous 🦄
}
}
You must ensure your code calls the completion handler once it has completed responding to the notification arrival, as per the Apple didReceiveRemoteNotification documentation.
∞ Notification delivery for iOS 13 and above
Apple has changed the way that remote notifications are delivered when an app is running in the background (i.e. opened but minimised by the user) in iOS 13 and above.
If you take no further action, when your app is running in the background the application:didReceiveRemoteNotification:fetchCompletionHandler:
method will not be called until the user brings the app to the foreground by tapping on the notification. The method call will also be delayed after the app enters the foreground, depending on the type of the received notification.
To ensure that the AppDelegate
method is called immediately after a notification is displayed when your app is running in the background and (as was the case with iOS 12 and below), you must implement a Notification Service Extension.
You can leave the NSE implementation unchanged from the example code that is generated by Xcode. This solution does not require any changes to the structure of your notification payloads. With the NSE implemented, iOS will make a call to application:didReceiveRemoteNotification:fetchCompletionHandler:
immediately after a notification is received by your app.
If you haven’t already, you will need to enable App Groups to allow your app to communicate with extensions. In your target’s Signing & Capabilities tab, click the “+ Capability” button and double-click “App Groups”. Click the checkmark box to enable the app group ID that was automatically created.
∞ Handling notifications and notification-related actions
If you want to customise how to present a received notification to a user when your app is running in the foreground, or you want to trigger some business logic when the user interacts with a notification, you need to implement some additional callback methods.
UNUserNotificationCenterDelegate
is the interface for handling incoming notifications and notification-related actions:
import UIKit
import PushNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
var window: UIWindow?
let beamsClient = PushNotifications.shared
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Set the delegate (to handle notification-related actions)
UNUserNotificationCenter.current().delegate = self
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
// Decide how the notification (that was received in the foreground)
// should be presented to the user
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
// Handle the user interaction with the notification
}
}
Please read the Apple documentation on handling notification-related actions for more information.
∞ While your app is closed
Apple does not offer a way to handle a notification that arrives when your app is closed (i.e. when the user has fully quit the application or the OS had decided to kill it while it is in the background). If this happens, the only way to handle the notification is to wait until it is opened by the user.
import UIKit
import PushNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
let beamsClient = PushNotifications.shared
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
if launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] != nil {
// The app was launched by the user tapping a notification
}
}
}
∞ Background updates
There are some additional considerations if you are publishing notifications that are designed to be processed in the background by your app (i.e. Notifications that are silent and not presented to the user directly). Their delivery will be throttled under certain circumstances, and iOS does not guarantee that all received background notifications are delivered to your apps.
Please read the Apple documentation on pushing background updates to your app for more information.