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.
Log on to the EMAS console.
Create an iOS application and obtain the AppKey and AppSecret.
See Quick Start.
Configure the APNs certificate.
Create and upload an 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
Version upgrade notice
If your current version is earlier than
1.9.9.3, do not directly upgrade to2.2.0,2.2.1, or3.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)
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' endNoteTo add the AlicloudPush dependency, edit the Podfile in your Xcode project's root directory. If a Podfile does not exist, run the
pod initcommand to create one. If CocoaPods is not installed, follow the instructions on the official CocoaPods website to install it.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
Download the latest SDK package from the Quick Start guide.
Unzip the package and add the frameworks:
Drag
CloudPushSDK.xcframework,AlicloudELS.xcframework, andUTDID.xcframeworkinto your project.
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:
Open your project settings.
Navigate to TARGETS.
Select Build Settings.
Locate the Linking section.
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.
Configure your Xcode project:
Navigate to Target > Signing & Capabilities and add the Push Notifications and Background Modes capabilities.
Under Background Modes, select Remote notifications.

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.
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.
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.