本章节介绍移动推送iOS SDK的集成操作。
前提条件
使用手动添加依赖方式需提前下载SDK包,请参见EMAS快速入门>下载SDK。
使用统一接入添加依赖需提前下载配置文件,请参见EMAS快速入门>下载配置文件。
已配置推送证书,请参见iOS 配置推送证书指南。
已阅读移动推送产品的使用限制。
样例代码
移动推送服务iOS SDK接入工程样例参见移动推送iOS Demo。
集成步骤
添加依赖
方式一:手动添加
解压下载好的SDK包,在Xcode中,把SDK包目录中的framework拖入对应Target下即可,在弹出框勾选Copy items if needed。
CloudPushSDK.framework AlicloudUtils.framework UTDID.framework
在工程项目中(Build Phases -> Link Binary With Libraries)添加以下库文件。
libz.tbd libresolv.tbd CoreTelephony.framework SystemConfiguration.framework libsqlite3.tbd
方式二:Pod集成
在Podfile中添加source,指定Master仓库和阿里云仓库。
source 'https://github.com/CocoaPods/Specs.git' source 'https://github.com/aliyun/aliyun-specs.git'
在终端执行
pod repo add
命令,拉取阿里云Pod仓库到本地 。pod repo add AliyunRepo https://github.com/aliyun/aliyun-specs.git
或手动拉取Pod仓库工程到CocoaPods仓库(默认为
~/.cocoapods/repos
)。git clone https://github.com/aliyun/aliyun-specs.git ~/.cocoapods/repos/
重要可执行
pod repo list
查看本地 Pod 仓库信息。pod repo list或git clone失败一般为GitHub账号publicKey配置问题,请仔细核对错误信息,Pod命令使用参考官方文档。
在您的工程中添加以下系统依赖库。
pod 'AlicloudPush', '2.1.0'
引入头文件
#import <CloudPushSDK/CloudPushSDK.h>
Objc配置
iOS端集成SDK时需要做
-ObjC
配置 ,即应用的 TARGETS -> Build Settings -> Linking -> Other Linker Flags ,需添加上-ObjC
这个属性,否则推送服务无法正常使用 。Other Linker Flags
中设定链接器参数-ObjC
,加载二进制文件时,会将 Objective-C 类和 Category 一并载入 ,若工程依赖多个三方库 ,将所有 Category 一并加载后可能发生冲突,可以使用-force_load
单独载入指定二进制文件,配置如下 :-force_load<framework_path>/CloudPushSDK.framework/CloudPushSDK
重要-force_load
指定的是二进制文件路径,而不是 Framework 目录。若指定为 Framework 目录,-force_load …path/xxx.framework,Xcode 会报出错误 ld: can’t map file, errno=22 file ‘…path/xxx.framework’ for architecture armv7。SDK初始化配置
在Xcode中把下载好的配置文件(AliyunEmasServices-Info.plist)拖入对应App Target下即可,在弹出框勾选Copy items if needed。
说明配置文件aliyunEmasServices-Info.plist中包含SDK初始化所需的配置信息,用户只需要调用autoInit接口进行初始化,无需手动输入配置信息。
下载配置文件的具体操作参考EMAS快速入门 > 下载配置文件。
请参照以下代码完成SDK的初始化。
说明您可在下载好的配置文件中获取Appkey、AppSecret,或参考EMAS快速入门。
百川云推送迁移过来的用户,不要使用百川平台获取到的Appkey、AppSecret,请使用EMAS平台获取的AppKey及AppSecret,否则会发生鉴权错误。
- (void)initCloudPush { // SDK初始化 [CloudPushSDK asyncInit:@"*****" appSecret:@"*****" callback:^(CloudPushCallbackResult *res) { if (res.success) { NSLog(@"Push SDK init success, deviceId: %@.", [CloudPushSDK getDeviceId]); } else { NSLog(@"Push SDK init failed, error: %@", res.error); } }]; }
向苹果APNs注册获取deviceToken,并上报到阿里云推送服务器:
/** * 注册苹果推送,获取deviceToken用于推送 * * @param application */ - (void)registerAPNS:(UIApplication *)application { if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) { // iOS 8 Notifications [application registerUserNotificationSettings: [UIUserNotificationSettings settingsForTypes: (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]]; [application registerForRemoteNotifications]; } else { // iOS < 8 Notifications [[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)]; } } /* * 苹果推送注册成功回调,将苹果返回的deviceToken上传到CloudPush服务器 */ - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { [CloudPushSDK registerDevice:deviceToken withCallback:^(CloudPushCallbackResult *res) { if (res.success) { NSLog(@"Register deviceToken success."); } else { NSLog(@"Register deviceToken failed, error: %@", res.error); } }]; } /* * 苹果推送注册失败回调 */ - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { NSLog(@"didFailToRegisterForRemoteNotificationsWithError %@", error); }
推送消息到来监听:
/** * 注册推送消息到来监听 */ - (void)registerMessageReceive { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMessageReceived:) name:@"CCPDidReceiveMessageNotification" object:nil]; } /** * 处理到来推送消息 * * @param notification */ - (void)onMessageReceived:(NSNotification *)notification { CCPSysMessage *message = [notification object]; NSString *title = [[NSString alloc] initWithData:message.title encoding:NSUTF8StringEncoding]; NSString *body = [[NSString alloc] initWithData:message.body encoding:NSUTF8StringEncoding]; NSLog(@"Receive message title: %@, content: %@.", title, body); }
通知打开监听:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 点击通知将App从关闭状态启动时,将通知打开回执上报 // [CloudPushSDK handleLaunching:launchOptions];(Deprecated from v1.8.1) [CloudPushSDK sendNotificationAck:launchOptions]; return YES; } /* * App处于启动状态时,通知打开回调 */ - (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo { NSLog(@"Receive one notification."); // 取得APNS通知内容 NSDictionary *aps = [userInfo valueForKey:@"aps"]; // 内容 NSString *content = [aps valueForKey:@"alert"]; // badge数量 NSInteger badge = [[aps valueForKey:@"badge"] integerValue]; // 播放声音 NSString *sound = [aps valueForKey:@"sound"]; // 取得Extras字段内容 NSString *Extras = [userInfo valueForKey:@"Extras"]; //服务端中Extras字段,key是自己定义的 NSLog(@"content = [%@], badge = [%ld], sound = [%@], Extras = [%@]", content, (long)badge, sound, Extras); // iOS badge 清0 application.applicationIconBadgeNumber = 0; // 通知打开回执上报 // [CloudPushSDK handleReceiveRemoteNotification:userInfo];(Deprecated from v1.8.1) [CloudPushSDK sendNotificationAck:userInfo]; }
重要iOS 10系统的设备需注意,基于工信部的要求,国行手机首次安装App时,会弹出一个询问用户“是否允许应用访问数据”的弹框。在用户点击
允许
前,或点击不允许
,App的网络环境是不同的,会导致推送SDK的初始化失败,推送服务不能正常使用。推送各接口内部是有重试机制
的,但是,建议用户在业务层,也要捕获处理SDK接口错误回调
,确保正确获知SDK接口调用状态。移动推送iOS SDK已经完成ATS适配,请求都以HTTPS发出,无需在Info.plist中进行ATS配置。
若SDK集成过程中出现
UTDID冲突
,请参考 阿里云-云产品SDK UTDID冲突解决方案。
初始化成功验证
根据SDK初始化回调结果查看是否成功。
if (res.success) { NSLog(@"Push SDK init success, deviceId: %@.", [CloudPushSDK getDeviceId]); } else { NSLog(@"Push SDK init failed, error: %@", res.error); }