阿里云 SDK配置 请依官方为主,毕竟已经很详细了
https://help.aliyun.com/document_detail/30072.html?spm=5176.doc30071.6.648.No5CmA
SDK配置流程:
1、导入下载好的 OneSDK
引入Framework 在 Xcode 中,直接把下载SDK目录中的framework 拖入对应 Target 下即可,在弹出框勾选 Copy items if needed。
oneSDK 目录结构:
- CloudPushSDK.framework
- AlicloudUtils.framework
- UTDID.framework
- UTMini.framework(阿里云平台下载的SDK无需依赖,百川平台下载的SDK需要依赖)
2、添加公共包依赖 在 Build Phases -> Link Binary With Libraries中,引入下列的公共包:
- libz.tbd
- libresolv.tbd
- CoreTelephony.framework
- SystemConfiguration.framework
- UserNotifications.framework(iOS 10+)
libsqlite3.tbd(阿里云平台下载的SDK无需依赖,百川平台下载的SDK需要依赖)
3、特殊要求
- 应用的 targets -> Build Settings -> Linking -> Other Linker Flags,请加上 -ObjC 这个属性,否则推送服务无法正常使用。
- 移动推送 iOS SDK 已经完成 ATS 适配,请求都以 HTTPS发出,无需在 Info.plist 中进行ATS配置。
4、在AppDelegate.m 里面完成配置
- 工程引入头文件
# import <CloudPushSDK/CloudPushSDK.h>
5、Xcode 设置
- 在 TARGET 下 Capabilities 勾选 Backgroud Modes -> Remote notifications,
- 主要是 iOS7 之后,苹果支持后台运行,如果这里打开后,当接收到远程推送后,程序在后台也可以做一些处理。
6、常遇见的问题:
- 在项目 target 中,打开Capabilitie —> Push Notifications,并会自动在项目中生成 .entitlement【ɪn'taɪt(ə)lmənt 权利 】文件。(很多同学升级后,获取不到 deviceToken,大概率是由于没开这个选项)
Capabilitie —> Push Notifications 自动生成 .entitlement - 确保添加了 UserNotifications.framework,并 import到 AppDelegate,记得实现 UNUserNotificationCenterDelegate 。
# import <UserNotifications/UserNotifications.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate,UNUserNotificationCenterDelegate>
附录一份具体代码:
//
// AppDelegate.m
// RAliMPushDemo
//
// Created by mac on 2017/7/14.
// Copyright © 2017年 rockey. All rights reserved.
//
#import "AppDelegate.h"
//导入头文件
#import <CloudPushSDK/CloudPushSDK.h>
static NSString *const testAppKey = @"*****";
static NSString *const testAppSecret = @"****************";
// iOS 10 notification
#import <UserNotifications/UserNotifications.h>
@interface AppDelegate ()<UNUserNotificationCenterDelegate>
@end
@implementation AppDelegate
{
// iOS 10通知中心
UNUserNotificationCenter *_notificationCenter;
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// 第一种情况:当程序处于关闭状态收到推送消息时,点击图标会调用该方法,那么消息给通过launchOptions这个参数获取到。
//当app未运行的时候
//在该方法中 didFinishLaunchingWithOptions:这个函数在你正常启动下 launchOptions 是空,如果你是从点击推送通知过来的,那么 laungchOptions里面会包含你的推送的内容。在这里就可以进行相应的处理,你就可以发一个通知,可以在rootViewController中接收执行相应的操作
if (launchOptions) {
NSLog(@"==============%@",launchOptions);
NSDictionary* pushNotificationKey = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (pushNotificationKey) {
//这里定义自己的处理方式
// 如果需要代码控制BadgeNum(icon右上角的数字)
[UIApplication sharedApplication].applicationIconBadgeNumber = 10;
}
}
// 是否允许通知 并向苹果APNs注册 获取deviceToken
[self authorizeNotification];
// 初始化阿里云推送SDK
[self initCloudPush];
// 监听推送消息到达 推送消息到来监听;
[self registerMessageReceive];
//4、点击通知 将App从关闭状态启动时,将通知打开回执上报
[CloudPushSDK sendNotificationAck:launchOptions];
return YES;
}
#pragma mark 初始化阿里云推送SDK
- (void)initCloudPush {
// 正式上线建议关闭
[CloudPushSDK turnOnDebug];
// 初始化SDK
[CloudPushSDK asyncInit:testAppKey appSecret:testAppSecret callback:^(CloudPushCallbackResult *res) {
if (res.success) {
NSLog(@"Push SDK init success, \n====================================deviceId: %@.", [CloudPushSDK getDeviceId]);
} else {
NSLog(@"Push SDK init failed, error: %@", res.error);
}
}];
}
//==========================================================
//是否允许通知
//并向苹果APNs注册 以获取deviceToken
- (void)authorizeNotification {
float systemVerson = [[UIDevice currentDevice].systemVersion floatValue];
if (systemVerson >= 10.0) {
// iOS 10 notifications
_notificationCenter = [UNUserNotificationCenter currentNotificationCenter];
_notificationCenter.delegate = self; //遵循协议
// 创建category,并注册到通知中心
[self createCustomNotificationCategory];
// 请求推送权限
[_notificationCenter requestAuthorizationWithOptions:UNAuthorizationOptionAlert | UNAuthorizationOptionBadge | UNAuthorizationOptionSound completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
// granted
NSLog(@"User authored notification.");
// 向APNs注册,获取deviceToken 系统注册
[[UIApplication sharedApplication] registerForRemoteNotifications];
} else {
// not granted
NSLog(@"User denied notification.");
}
}];
[_notificationCenter getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
//进行判断做出相应的处理
if (settings.authorizationStatus == UNAuthorizationStatusNotDetermined) {
NSLog(@"未选择");
} else if (settings.authorizationStatus == UNAuthorizationStatusDenied) {
NSLog(@"未授权");
} else if (settings.authorizationStatus == UNAuthorizationStatusAuthorized){
NSLog(@"已授权");
}
}];
} else if (systemVerson >= 8.0) {//适配 iOS_8, iOS_10.0
//提出弹窗,授权是否允许通知
UIUserNotificationSettings * settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
// 注册远程通知 (iOS_8+)
[[UIApplication sharedApplication] registerForRemoteNotifications];
if ([[UIApplication sharedApplication] currentUserNotificationSettings].types == UIUserNotificationTypeNone) { //判断用户是否打开通知开关
NSLog(@"没有打开");
}else {
NSLog(@"已经打开");
}
} else { //适配 iOS 8 之前的版本 3_0, 8_0
UIRemoteNotificationType types = UIRemoteNotificationTypeBadge|UIRemoteNotificationTypeSound|UIRemoteNotificationTypeAlert;
[[UIApplication sharedApplication]registerForRemoteNotificationTypes:types];
if ([[UIApplication sharedApplication] enabledRemoteNotificationTypes] == UIRemoteNotificationTypeNone) { //判断用户是否打开通知开关
}
}
}
//====================================================
//APNs推送注册成功回调,将苹果返回的deviceToken上传到CloudPush服务器
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken NS_AVAILABLE_IOS(3_0) {
[CloudPushSDK registerDevice:deviceToken withCallback:^(CloudPushCallbackResult *res) {
if (res.success) {
NSLog(@"Register deviceToken success, \n===================================deviceToken: %@", [CloudPushSDK getApnsDeviceToken]);
} else {
NSLog(@"Register deviceToken failed, error: %@", res.error);
}
}];
}
// APNs注册失败回调
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(@"didFailToRegisterForRemoteNotificationsWithError \n===========================%@", error);
}
//=====================================================================
//====== 监听 消息 到达 并处理推送的消息====================================
- (void)registerMessageReceive {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMessageReceived:) name:@"CCPDidReceiveMessageNotification" object:nil];
}
- (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(@"======================= title: %@, content: %@.", title, body);
}
//==============================================================
//App处于前台时,如果收到远程通知则调用该处理方法 iOS(3_0, 10_0) 程序处于后台的时候是无法接收到推送信息的
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
//通过远程通知进入应用时候
application.applicationIconBadgeNumber = 0;
/*
1、在ios7上时,只要收到通知,就会调起didReceiveRemoteNotification
1.2、当程序处于前台工作时,这时候若收到消息推送,会调用该这个方法
1.3、当程序处于后台运行时,这时候若收到消息推送,如果点击消息或者点击消息图标时,也会调用该这个方法
2、但在iOS_8 上时,只有app前台运行或充电时,才会调起didReceiveRemoteNotification
2.1、并且 iOS_8 得开启后台模式下接收远程通知。工程配置 TARGATES --> Capabilities BackgroundModes -> ON 选择 RemoteNotification
*/
//2.2、处理方法:
if (application.applicationState == UIApplicationStateActive) {
//前台时候
if ([[userInfo objectForKey:@"aps"] objectForKey:@"alert"]!=NULL) {
//处理情况
}
} else {
//后台时候
//这里定义自己的处理方式
}
/*
iOS 如何判断是点击推送信息进入还是点击app图标进入程序
设备接到apns发来的通知,应用处理通知有以下几种情况:
1. 应用还没有加载
这时如果点击通知的显示按钮,会调用didFinishLaunchingWithOptions,不会调用didReceiveRemoteNotification方法。
如果点击通知的关闭按钮,再点击应用,只会调用didFinishLaunchingWithOptions方法。
2. 应用在前台(foreground)
这时如果收到通知,会触发didReceiveRemoteNotification方法。
3. 应用在后台
(1)此时如果收到通知,点击显示按钮,会调用didReceiveRemoteNotification方法。
(2)点击关闭再点击应用,则上面两个方法都不会被调用这时,只能在applicationWillEnterForeground或者applicationDidBecomeActive,根据发过来通知中的badge进行判断是否有通知,然后发请求获取数据
*/
// 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);
NSLog(@"content = [%@], badge = [%ld], sound = [%@],", content, (long)badge, sound);
// iOS badge 清0
application.applicationIconBadgeNumber = 0;
// 通知打开回执上报
// [CloudPushSDK handleReceiveRemoteNotification:userInfo];(Deprecated from v1.8.1)
[CloudPushSDK sendNotificationAck:userInfo];
}
//当应用程序被用户从远程通知中选择操作时激活。调用该方法处理程序( iOS(8_0, 10_0))
- (void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler {
}
//iOS 7+ //不论是前台还是后台只要有远程推送都会调用
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler {
NSLog(@"========================前台后台都会调用");
/*
建议使用该方法,还有一个作用。根据苹果给出的文档,系统给出30s的时间对推送的消息进行处理,此后就会运行CompletionHandler程序块。
在处理这类推送消息(即程序被启动后接收到推送消息)的时候,通常会遇到这样的问题,
就是当前的推送消息是当前程序正在前台运行时接收到的,还是说是程序在后台运行,用户点击系统消息通知栏对应项进入程序时而接收到的?这个其实很简单,用下面的代码就可以解决:
*/
if (application.applicationState == UIApplicationStateActive) {
NSLog(@"active");
//程序当前正处于前台
/*关于userInfo的结构,参照苹果的官方结构:
{
"aps" : {
"alert" : "You got your emails.",
"badge" : 9,
"sound" : "bingbong.aiff"
"acme1" : "bar",
"acme2" : 42
}
即key aps对应了有一个字典,里面是该次推送消息的具体信息。具体跟我们注册的推送类型有关。另外剩下的一些key就是用户自定义的了。
*/
}
else if(application.applicationState == UIApplicationStateInactive)
{
NSLog(@"inactive");
//程序处于后台
}
}
//只有当应用程序位于前台时,该方法才会在委托上调用。如果方法未被执行或处理程序没有及时调用,则通知将不会被提交。应用程序可以选择将通知呈现为声音、徽章、警报和/或通知列表中。此决定应基于通知中的信息是否对用户可见。
//iOS 10 + 最后实现以下两个代理方法。 以后的 App处于前台状态时,通知打开回调
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
NSLog(@"Userinfo %@",notification.request.content.userInfo);
//NSLog(@"Receive a notification in foregound.");
//1. 处理通知 处理iOS 10通知,并上报通知打开回执
[self handleiOS10Notification:notification];
// 通知不弹出
//completionHandler(UNNotificationPresentationOptionNone);
//功能:可设置是否在应用内弹出通知
//2. 处理完成后调用 completionHandler ,用于指示在前台显示通知的形式
completionHandler(UNNotificationPresentationOptionAlert);
// 通知弹出,且带有声音、内容和角标
//completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge);
}
/*
* 当APP处于后台(iOS 10+) 触发通知动作时回调,比如点击、删除通知和点击自定义action
*/
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler{
NSLog(@"Userinfo %@",response.notification.request.content.userInfo);
NSString *userAction = response.actionIdentifier;
if ([userAction isEqualToString:UNNotificationDefaultActionIdentifier]) {
// NSLog(@"User opened the notification.");
// 处理iOS 10通知,并上报通知打开回执
[self handleiOS10Notification:response.notification];
}
// 通知dismiss,category创建时传入UNNotificationCategoryOptionCustomDismissAction才可以触发
if ([userAction isEqualToString:UNNotificationDismissActionIdentifier]) {
NSLog(@"User dismissed the notification.");
}
NSString *customAction1 = @"action1";
NSString *customAction2 = @"action2";
// 点击用户自定义Action1
if ([userAction isEqualToString:customAction1]) {
NSLog(@"User custom action1.");
}
// 点击用户自定义Action2
if ([userAction isEqualToString:customAction2]) {
NSLog(@"User custom action2.");
}
completionHandler();
}
// 1. 处理在前台收到通知 (iOS 10 + 并上报通知打开回执)
- (void)handleiOS10Notification:(UNNotification *)notification {
UNNotificationRequest *request = notification.request;
UNNotificationContent *content = request.content;
NSDictionary *userInfo = content.userInfo;
// 通知时间
NSDate *noticeDate = notification.date;
// 标题
NSString *title = content.title;
// 副标题
NSString *subtitle = content.subtitle;
// 内容
NSString *body = content.body;
// 角标
int badge = [content.badge intValue];
// 取得通知自定义字段内容,例:获取key为"Extras"的内容
//NSString *extras = [userInfo valueForKey:@"Extras"];
//NSLog(@"Notification, date: %@, title: %@, subtitle: %@, body: %@, badge: %d, extras: %@.", noticeDate, title, subtitle, body, badge, extras);
NSLog(@"Notification, date: %@, title: %@, subtitle: %@, body: %@, badge: %d", noticeDate, title, subtitle, body, badge);
// 通知打开回执上报
[CloudPushSDK sendNotificationAck:userInfo];
}
//=============================================================
#pragma mark 创建category,并注册到通知中心
- (void)createCustomNotificationCategory {
// 自定义`action1`和`action2`
UNNotificationAction *action1 = [UNNotificationAction actionWithIdentifier:@"action1" title:@"test1" options: UNNotificationActionOptionNone];
UNNotificationAction *action2 = [UNNotificationAction actionWithIdentifier:@"action2" title:@"test2" options: UNNotificationActionOptionNone];
// 创建id为`test_category`的category,并注册两个action到category
// UNNotificationCategoryOptionCustomDismissAction表明可以触发通知的dismiss回调
UNNotificationCategory *category = [UNNotificationCategory categoryWithIdentifier:@"test_category" actions:@[action1, action2] intentIdentifiers:@[] options:UNNotificationCategoryOptionCustomDismissAction];
// 注册category到通知中心
[_notificationCenter setNotificationCategories:[NSSet setWithObjects:category, nil]];
}
- (void)applicationWillResignActive:(UIApplication *)application {
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
}
//2、当app在后台运行时 激活APP时会走
- (void)applicationDidBecomeActive:(UIApplication *)application {
NSLog(@"在这里面里可以对推送消息做响应的处理");
//点击app 从后台进入应用时,badge 的处理
application.applicationIconBadgeNumber = 0;
}
- (void)applicationWillTerminate:(UIApplication *)application {
}
@end
网友评论