iOS SDK integration

更新时间:
复制 MD 格式

This document shows you how to integrate and configure the Alibaba Cloud Mobile Push SDK for iOS. You will learn how to initialize the SDK, request notification permissions, and handle messages and notifications.

Prerequisites

  • Create an EMAS application and obtain credentials.

  • Configure the APNs certificate.

  • Meet the development environment requirements.

    • Xcode: 12.0 or later

    • iOS deployment target: iOS 12.0 or later

    • CocoaPods: 1.11.0 or later

    • Swift version: Swift 5.x. Swift 6 is not supported.

Integration steps

SDK dependencies

Warning

Version upgrade notice

  • If your current version is earlier than 1.9.9.3, do not directly upgrade to 2.2.0, 2.2.1, or 3.0.0, because this will reset the device ID.

  • If your AppKey was created for a dual-platform application (sharing the same AppKey for both Android and iOS), you cannot upgrade to version 3.0.0 or later. Create separate applications for the Android and iOS platforms, obtaining a unique AppKey for each, and integrating with the latest SDK.

CocoaPods (recommended)

  1. Create or modify your Podfile:

    source 'https://github.com/CocoaPods/Specs.git'
    source 'https://github.com/aliyun/aliyun-specs.git'
    
    platform :ios, '11.0'
    use_frameworks!
    
    target 'YourTarget' do
      pod 'AlicloudPush', '~> 3'
    end
    Note

    To add the AlicloudPush dependency, edit the Podfile in your Xcode project's root directory. If a Podfile does not exist, run the pod init command to create one. If CocoaPods is not installed, follow the instructions on the official CocoaPods website to install it.

  2. Run the installation commands:

    pod repo update AliyunRepo
    pod install
    
    # If you have not added the Alibaba Cloud CocoaPods repository, run the following command first.
    # pod repo add AliyunRepo https://github.com/aliyun/aliyun-specs.git

Manual integration

  1. Download the latest SDK package from the Quick Start guide.

  2. Unzip the package and add the frameworks:

    1. Drag CloudPushSDK.xcframework, AlicloudELS.xcframework, and UTDID.xcframework into your project.

Note
  • Dependencies

    • Versions 3.1.0 and later:

      • Includes the CloudPushSDK, AlicloudELS, and UTDID dependency libraries.

    • Version 3.0.0:

      • Includes the CloudPushSDK and AlicloudELS dependency libraries.

    • Versions 2.2.0 to 3.0.0:

      • Includes the CloudPushSDK dependency library.

    • Versions earlier than 2.2.0:

      • Includes the CloudPushSDK, UTDID, and AlicloudUtils dependency libraries.

  • Xcode compatibility

    When using an earlier version of Xcode, you may need to manually add the following system libraries to ensure compatibility:

    • libresolv.tbd

    • CoreTelephony.framework

    • SystemConfiguration.framework

    • libsqlite3.tbd

  • Linker settings

    If you encounter issues at runtime, try adding the -ObjC linker flag:

    1. Open your project settings.

    2. Navigate to TARGETS.

    3. Select Build Settings.

    4. Locate the Linking section.

    5. In Other linker flags, add -ObjC.

SDK initialization

Initialize the SDK in your AppDelegate.

import CloudPushSDK

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
        CloudPushSDK.setLogLevel(MPLogLevel.info);
        
        // Initialize the SDK
        CloudPushSDK.start(withAppkey: "Your AppKey", appSecret: "Your AppSecret") { res in
            if res.success {
                print("SDK initialization successful | DeviceID: \(CloudPushSDK.getDeviceId() ?? "N/A")")
            } else {
                print("Initialization failed: \(res.error?.localizedDescription ?? "Unknown error")")
            }
        }
        
        return true
    }
}
#import "CloudPushSDK/CloudPushSDK.h"

@implementation AppDelegate

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

    [CloudPushSDK setLogLevel:MPLogLevelInfo];
    
    // Initialize the SDK
    [CloudPushSDK startWithAppkey:@"Your AppKey" 
                        appSecret:@"Your AppSecret" 
                        callback:^(CloudPushCallbackResult *result) {
        if (result.success) {
            NSLog(@"SDK initialization successful | DeviceID: %@", [CloudPushSDK getDeviceId]);
        } else {
            NSLog(@"Initialization failed: %@", result.error);
        }
    }];
    
    return YES;
}
@end

APNs push configuration

Enable push permissions to request a device token from Apple's servers and report it to the Alibaba Cloud push server.

  1. Configure your Xcode project:

    1. Navigate to Target > Signing & Capabilities and add the Push Notifications and Background Modes capabilities.

    2. Under Background Modes, select Remote notifications.image

  2. Request user authorization for notifications. The following code provides an example.

// Request user authorization
func setupAPNs() {
    let center = UNUserNotificationCenter.current()
    center.requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
        DispatchQueue.main.async {
            if granted {
                UIApplication.shared.registerForRemoteNotifications()
            }
            print("Push permission status: \(granted ? "Granted" : "Denied")")
        }
    }
}

// Callback for successful APNs device registration
func application(_ application: UIApplication,
               didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    CloudPushSDK.registerDevice(deviceToken) { result in
        let status = result.success ? "succeeded" : "failed"
        print("Device token reporting \(status)")
    }
}
- (void)setupAPNs {
    UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
    
    [center requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge)
                          completionHandler:^(BOOL granted, NSError * _Nullable error) {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (granted) {
                [[UIApplication sharedApplication] registerForRemoteNotifications];
            }
            NSLog(@"Push permission status: %@", granted ? @"Granted" : @"Denied");
        });
    }];
}

// Callback for successful APNs device registration
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    [CloudPushSDK registerDevice:deviceToken withCallback:^(CloudPushCallbackResult *result) {
        NSString *status = result.success ? @"succeeded" : @"failed";
        NSLog(@"Device token reporting %@", status);
    }];
}

Message handling

A message is a passthrough payload containing a title and content, sent through Alibaba Cloud's proprietary channel. A message does not trigger a sound or vibration on the device and can only be received when your app is online. When your app receives a message, you can run custom code based on its content.

// Subscribe to messages
NotificationCenter.default.addObserver(self, 
                                     selector: #selector(onMessageReceived(_:)), 
                                     name: NSNotification.Name("CCPDidReceiveMessageNotification"), 
                                     object: nil)

@objc func onMessageReceived(_ notification: Notification) {
    guard let data = notification.object as? [String: Any],
          let title = data["title"] as? String,
          let content = data["content"] as? String else {
        return
    }
    print("Receive message title: \(title), content: \(content)")
}
// Subscribe to messages
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(onMessageReceived:)
                                             name:@"CCPDidReceiveMessageNotification"
                                           object:nil];

- (void)onMessageReceived:(NSNotification *)notification {
    NSDictionary *data = [notification object];
    NSString *title = data[@"title"];
    NSString *content = data[@"content"];
    
    NSLog(@"Receive message title: %@, content: %@.", title, content);
}

Notification handling

A notification is delivered through Apple's servers and can be displayed on the lock screen. Your app does not need to be online to receive notifications; the device only needs a network connection. Your app can handle notifications in several scenarios:

Foreground notification callback

When your app is in the foreground, the system calls your delegate method. In this method, you can execute custom logic and decide whether to display the notification.

Notification tap callback

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

Silent notification callback

When a silent notification is sent, the system calls your delegate method while your app is in the foreground or background.

Sample code

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 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 payload. 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 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];

    // Decide whether to display the notification.
    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 {
    // Get custom key-value pairs from the notification payload. 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 notification tap
    [CloudPushSDK sendNotificationAck:userInfo];
}

// ......
@end

Integration verification

After running the app, check the Xcode console and confirm that a log message similar to the following appears:

2025-03-11 11:26:33.854 INFO [CloudPushSDK] Initialization successful
====================
DeviceId: a1b693a9fced4c22aab3cdfe3fbe5a05
DeviceToken: 76aa3065ca246c81ad1b640715f45f3f8d16fea38ca4fb2917cf34b7249bd803
SdkVersion: 3.0.0
====================

This log indicates a successful SDK initialization. You can now query for the device in the EMAS console. If the device appears, the integration is successful.

  • ACCS: Successful registration with the Alibaba Cloud proprietary channel.

  • APNS: Successful registration with the Apple Push Notification service (APNs).

Ensure that both channels show a successful status to verify that the push service is configured correctly.image

Extension receipt SDK integration (optional)

iOS does not natively provide receipts for notification delivery or display. To track notification reach status, you can integrate our extension receipt SDK (ext SDK) into a Notification Service Extension. This SDK proactively reports a receipt log of type ext_ack before the notification is displayed. This log indicates that the notification has reached the device and is ready for presentation.

After integration, you can filter receipt logs by the ext_ack event type to estimate whether notifications reached user devices. For detailed integration instructions, API documentation, and important considerations, see Integrate the iOS extension receipt SDK.

Note
  • This solution consumes extra device battery because it makes a network request from the Notification Service Extension to report the receipt.

  • This may cause a delay of up to tens of seconds in notification display, because the notification is shown only after the receipt is reported.

  • Use this feature only if you require strict monitoring of notification delivery rates and can accept the side effects.

  • When sending push notifications with the OpenAPI, you must explicitly enable the extension receipt capability.

Further reading

  1. Troubleshooting iOS SDK integration errors

  2. Troubleshooting iOS push notification failures

  3. Troubleshooting issues with obtaining a device token on iOS

  4. Mobile Push for iOS sample project

  5. Mobile Push product limitations