Notification handling interface

Updated at:

This document describes how to handle notifications in an iOS application.

Introduction to notifications

Notifications are messages that Apple servers send to user devices. These messages can appear on the lock screen. Your application does not need to be running to receive notifications. The device only needs a network connection to receive and display them.

Handle notifications

Due to iOS system limitations, notifications are not automatically processed by your application. Different types of notifications must be handled separately. The following sections describe common scenarios for handling notifications:

Foreground notification callback

When your application is in the foreground, the system delivers the notification by calling a delegate method that you implement. In this method, you can run your custom logic and decide whether to display the notification.

Click notification callback

When a user taps a notification, the system opens your application and calls a delegate method to handle the tap event.

Silent notification callback

When a silent notification is delivered, the system wakes your application and calls your delegate method. This occurs whether your application is in the foreground or the background.

Code example

import UIKit
import CloudPushSDK
import UserNotifications

@main
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Initialize the SDK
        // ...
        
        // Set the notification center delegate
        UNUserNotificationCenter.current().delegate = self
        
        return true
    }
    
    // MARK: - UNUserNotificationCenterDelegate
    
    func userNotificationCenter(_ center: UNUserNotificationCenter, 
                              willPresent notification: UNNotification,
                              withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        print("Received foreground notification callback")
        handleUserInfo(userInfo: notification.request.content.userInfo)
        
        // Set the notification presentation options
        completionHandler([.alert, .sound])
    }
    
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                              didReceive response: UNNotificationResponse,
                              withCompletionHandler completionHandler: @escaping () -> Void) {
        print("Received notification tap callback")
        handleUserInfo(userInfo: response.notification.request.content.userInfo)
        completionHandler()
    }
    
    func application(_ application: UIApplication,
                   didReceiveRemoteNotification userInfo: [AnyHashable : Any],
                   fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        print("Received silent notification callback")
        handleUserInfo(userInfo: userInfo)
        completionHandler(.newData)
    }
    
    func handleUserInfo(userInfo: [AnyHashable : Any]) {
        // Get custom key-value pairs from the notification dictionary. For example:
        // let customValue = userInfo["customKey"] as? String
        
        guard let aps = userInfo["aps"] as? [String: Any],
              let alert = aps["alert"] as? [String: String],
              let title = alert["title"],
              let body = alert["body"] else {
            return
        }
        
        print("Notification content: title=\(title), body=\(body)")
        
        // Report the notification tap
        CloudPushSDK.sendNotificationAck(userInfo)
    }
    
    // ...
}
#import "AppDelegate.h"
#import "CloudPushSDK/CloudPushSDK.h"
#import <UserNotifications/UserNotifications.h>

@interface AppDelegate () <UNUserNotificationCenterDelegate>
@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Initialize the SDK
    // ...
    
    // Set the notification center delegate
    [UNUserNotificationCenter currentNotificationCenter].delegate = self;
    
    return YES;
}

#pragma mark - Receive Notifications
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
    NSLog(@"Received foreground notification callback");
    [self handleUserInfo:notification.request.content.userInfo];

    // You can decide whether to display an alert based on your needs.
    completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionSound);
}

- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
    NSLog(@"Received notification tap callback");
    [self handleUserInfo:response.notification.request.content.userInfo];
    completionHandler();
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    NSLog(@"Received silent notification callback");
    [self handleUserInfo:userInfo];
    completionHandler(UIBackgroundFetchResultNewData);
}

- (void)handleUserInfo:(NSDictionary *)userInfo {
    // You can get custom key-value pairs from the notification dictionary. For example:
    // NSString *customValue = userInfo[@"customKey"];
    
    NSString *title = userInfo[@"aps"][@"alert"][@"title"];
    NSString *body = userInfo[@"aps"][@"alert"][@"body"];
    NSLog(@"Notification content: title=%@, body=%@", title, body);
    
    // Report the notification tap
    [CloudPushSDK sendNotificationAck:userInfo];
}

// ...
@end

The userInfo object

The userInfo object in the code examples is a dictionary that is passed to the notification callback method. It has the following format:

{
  "aps" : {
    "category" : "test_category",
    "badge" : 2,
    "sound" : "default",
    "interruption-level" : "active",
    "relevance-score" : 0.5,
    "alert" : {
      "title" : "notification title",
      "subtitle" : "this is notification subtitle",
      "body" : "this is notification body"
    },
    "thread-id" : "test_thread_id"
  },
  "i" : 11153971268435968,
  "customKey1" : "customValue1",
  "customKey2" : "customValue2"
}

In this object, aps is the Apple Push Notification service (APNs) payload. The i field is the Alibaba Cloud Mobile Push message ID. customKey is a custom field that you specify when you use the Alibaba Cloud push API for advanced pushes.