一、什么叫极光推送
极光推送(JPush)是独立的第三方云推送平台,致力于为全球移动应用开发者提供移动消息推送服务。极光,是国内领先的移动大数据的服务商。拥有开发者服务、广告服务和数据服务三大产品体系,开发者服务助力app精细运营,覆盖极光推送、极光IM、极光短信、极光统计、社会化分享、极光认证,广告服务(极光效果通助力精准营销,数据服务,极光大数据 助力企业运营。
说白了,极光推送类似于我们每天在手机上接收到的消息。那我们怎么在自己的app中实现这种功能呢?
二、实现极光推送的准备工作
准备的工作主要步骤:
第一步:在苹果开发者网站中利用开发者账号创建出app Id,即创建应用程序ID。
第二步:配置极光推送端需要的两种证书:开发证书,生产证书。
第三步:把配置好的证书,传递到极光开发平台上。
详细操作过程:
第一步:创建App ID
1.登录苹果开发者网站,登录开发者账户。
2.添加新的APP ID,并填写相关的Name和Bundle ID。
注意:
bundle ID可以翻译成包ID,也可以叫APP ID 或应用ID,它是每一个ios应用的全球唯一标识。无论代码怎么改,图标和应用名称怎么换,只要bundle id没变,ios系统就认为这是同一个应用。每开发一个新应用,首先都需要到member center->identifier->APP IDS去创建一个bundle id。但是bundle id分为两种:
Explicit App ID(明确的APP ID),一般格式是:com.domainname.appname。这种id只能用在一个app上。每一个新应用都要创建一个,其中domainname可以使用公司的缩写,全拼。
Wildcard App ID(通配符APP ID), 一般格式是:com.domainname.*。这种id可以用在多个应用上,虽然方便,但是使用这种id的应用不能使用通知功能,所以并不常用。
3.为创建的APP ID 开启Push Notification功能,已有的appID也可以继续添加Push Notification功能。
4.完成以上操作,依次点击Continue,点击Register,完成APP ID的注册。
第二步:配置开发证书,生产证书,以及相关证书的导出
首先要有一个CSR文件(Certificate Signing Request)
1.打开系统里自带的“钥匙串访问”,创建 Certificate Signing Request。
2.填写“用户邮箱”和“常用名称” ,并选择“存储到磁盘”,证书文件后缀为.certSigningRequest 。
配置开发证书流程:
1.开发证书的生成(点击左侧的development)
2.点击Continue,来进入到AppId界面
3.说明让自己上传的CSR(Certificate Signing Request)文件,然后Continue。
4.上传请求生成的CSR文件,然后Continue(如果不知道怎么生成CSR文件,请看这里的链接)
5.生成证书后,点击downLoad将证书下载到本地中,后缀为.cer文件。
6.点击生成的证书,在钥匙串中打开,导出为.p12文件,并存储到本地。
配置生产证书流程:
1.生产证书的生成(点击左侧的Production),其他的操作步骤都是类似于上面的配置开发证书。
生成好的证书展示:
第三步:证书上传极光平台
如果你还没有注册极光账号,请看这里--->连接
在极光官网上登录开发账号,点击极光开发者服务,找到推送设置,选择iOS,选中证书,进行证书的配置。就是一些简单的文件上传,期间可能要输入一些密码,这个密码就是证书导出时候输入的密码,这个千万不要弄错了!
至此,一些关于极光推送的准备工作全部完成,接下来就让我们开始在自己的项目中进行实战吧。
三、项目中极光SDK的配置,代码功能的实现
-
第一步:导入极光SDK
方法1:可以通过CocoaPods进行导入JPush。
方法2:手动导入可以参考链接:极光文档-iOS SDK集成指南
第二步:代码功能的实现
1.进入项目中的appDelegate导入头文件,遵循代理
#import <JPUSHService.h>
#ifdef NSFoundationVersionNumber_iOS_9_x_Max
#import <UserNotifications/UserNotifications.h>
#endif
<JPUSHRegisterDelegate,UNUserNotificationCenterDelegate>
2.在didFinishLaunchingWithOptions中进行JPush的相关初始化设置
[self inintJPushWithOption:launchOptions];
-(void)inintJPushWithOption:(NSDictionary *)launchOptions{
// Override point for customization after application launch.
// NSString *advertisingId = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
//添加APNs代码 JPush的初始化操作
self.messageSum = 0;
JPUSHRegisterEntity * entity = [[JPUSHRegisterEntity alloc] init];
entity.types = JPAuthorizationOptionAlert|JPAuthorizationOptionBadge|JPAuthorizationOptionSound;
// if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) {
// //可以添加自定义categories
// // if ([[UIDevice currentDevice].systemVersion floatValue] >= 10.0) {
// // NSSet<UNNotificationCategory *> *categories;
// // entity.categories = categories;
// // }
// // else {
// // NSSet<UIUserNotificationCategory *> *categories;
// // entity.categories = categories;
// // }
// }
//注册极光
[JPUSHService registerForRemoteNotificationConfig:entity delegate:self];
//如不需要使用IDFA,advertisingIdentifier 可为nil
// isProduction NO为开发环境,YES为生产环境
[JPUSHService setupWithOption:launchOptions appKey:appKey
channel:channel
apsForProduction:isProduction
advertisingIdentifier:nil];
//2.1.9版本新增获取registration id block接口。
[JPUSHService registrationIDCompletionHandler:^(int resCode, NSString *registrationID) {
if(resCode == 0){
NSLog(@"registrationID获取成功:%@",registrationID);
}
else{
NSLog(@"registrationID获取失败,code:%d",resCode);
}
}];
//☆☆☆ 添加一个notification来捕捉极光的自定义消息 只能在前台展示
NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
[defaultCenter addObserver:self selector:@selector(networkDidReceiveMessage:) name:kJPFNetworkDidReceiveMessageNotification object:nil];
//极光推送的角标问题
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
[JPUSHService setBadge:0];
3.注册DevieceToken
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
/// Required - 注册 DeviceToken
NSLog(@"system deviceToken is %@",deviceToken);
[JPUSHService registerDeviceToken:deviceToken];
}
4.接下来我们处理一下极光推送的回调方法
#pragma mark ----- 获取消息数据的处理
//handle JPush customize remote message 处理从服务器端发送来的极光通知
- (void)networkDidReceiveMessage:(NSNotification *)notification{
self.messageSum++;
NSDictionary * userInfo = [notification userInfo];
NSString *title = [userInfo valueForKey:@"title"];
//先将jsonStr转换为字典
NSDictionary *content = [self dictionaryWithJsonString:[userInfo valueForKey:@"content"]];
//来一个url的参数
self.messageUrl = [content valueForKey:@"messageLink"];
self.messageNavTitle = [content valueForKey:@"messageName"];
NSString * messageTitle = [content valueForKey:@"messageTitle"];
NSString * messageContent = [content valueForKey:@"messageContent"];
NSString *messageID = [userInfo valueForKey:@"_j_msgid"];
NSDictionary *extras = [userInfo valueForKey:@"extras"];
NSString *customizeField1 = [extras valueForKey:@"customizeField1"]; //服务端传递的Extras附加字段,key是自己定义的
NSLog(@"这里获取的参数值title:%@,content:%@,extra:%@,messageID:%lu,messaeTitle:%@,messageContent-%@",title,content,extras,(unsigned long)messageID,messageTitle,messageContent);
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd hh:mm:ss"];
self.messageTime = [NSDateFormatter localizedStringFromDate:[NSDate date]
dateStyle:NSDateFormatterNoStyle
timeStyle:NSDateFormatterMediumStyle];
NSString *currentContent = [NSString
stringWithFormat:
@"APP代理中收到自定义消息:%@\ntitle:%@\ncontent:%@\nextra:%@\nmessage:%ld\n,messageCount:%d\n",
[NSDateFormatter localizedStringFromDate:[NSDate date]
dateStyle:NSDateFormatterNoStyle
timeStyle:NSDateFormatterMediumStyle],
title, content, [self logDic:extras],(unsigned long)messageID,self.messageSum];
NSLog(@"代理中获取到数据参数为:%@", currentContent);
//跳转啊 啊啊
// [self goToMssageViewControllerWith:userInfo];
/**
* 通过 UNUserNotificationCenter 将自定义的消息推送到前台显示
*/
//建立本地通知,如果程序在后台的时候也会收到推送通知一样的消息。也可以判断在程序在前台的时候做一些特别的操作。
// [JPUSHService setLocalNotification:[NSDate dateWithTimeIntervalSinceNow:3] alertBody:messageContent badge:1 alertAction:messageTitle identifierKey:nil userInfo:userInfo soundName:nil];
NSString *dateString = [dateFormatter stringFromDate:[NSDate date]];
UNMutableNotificationContent * uucontent = [[UNMutableNotificationContent alloc] init];
uucontent.title = messageTitle;
uucontent.body = messageContent;
uucontent.badge = @(self.messageSum);//@(+1);
NSString *requestIdentifier = [NSString stringWithFormat:@"%@%@",dateString,MANAGER_ID];
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:requestIdentifier content:uucontent trigger:nil];
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
//界面的跳转 啊
// [self goToMssageViewControllerWith:userInfo];
}];
//移除通知
[[NSNotificationCenter defaultCenter] removeObserver:self
name:kJPFNetworkDidLoginNotification
object:nil];
}
5.iOS10以上接收消息的处理
//iOS 10以上接收消息处理消息
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
NSDictionary * userInfo = response.notification.request.content.userInfo;
UNNotificationRequest *request = response.notification.request; // 收到推送的请求
UNNotificationContent *content = request.content; // 收到推送的消息内容
NSNumber *badge = content.badge; // 推送消息的角标
NSString *body = content.body; // 推送消息体
UNNotificationSound *sound = content.sound; // 推送消息的声音
NSString *subtitle = content.subtitle; // 推送消息的副标题
NSString *title = content.title; // 推送消息的标题
NSLog(@"iOS10122 点击通知栏收到远程通知:%@", userInfo);
if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
[JPUSHService handleRemoteNotification:userInfo];
//[self logDic:userInfo]
NSLog(@"iOS10 点击通知栏收到远程通知:%@", userInfo);
//点击通知栏进行消息界面的跳转 0
[[UIApplication sharedApplication]setApplicationIconBadgeNumber:0];
[JPUSHService setBadge:0];//清空Jpush中存储的badge值
//点击消息进行跳转到消息的详情界面中
[self goToMssageViewControllerWith:userInfo];
}
else {
// 判断为本地通知
NSLog(@"iOS10 收到本地通知:{\nbody:%@,\ntitle:%@,\nsubtitle:%@,\nbadge:%@,\nsound:%@,\nuserInfo:%@\n}",body,title,subtitle,badge,sound,userInfo);
//处理自定义参数的数据
//点击通知栏进行消息界面的跳转
[[UIApplication sharedApplication]setApplicationIconBadgeNumber:0];
[JPUSHService setBadge:0];//清空Jpush中存储的badge值
//点击消息进行跳转到消息的详情界面中
[self goToMssageViewControllerWith:content];
[JPUSHService handleRemoteNotification:userInfo];
}
completionHandler(); // 系统要求执行这个方法 UIBackgroundFetchResultNewData
}
- 第三步:进行简单的极光推送的测试
详细的可以见下面的demo 极光官方文档-iOS SDK+demo下载
四、相关的问题的集中处理
这里可以参考一下链接:极光官方文档-iOS SDK FAQ
至此极光推送部分简单的实现已经全部完成,后面将会继续更新编辑新加的内容。
谢谢观赏!
相关的参考文献:
极光官方文档
极光官方文档-iOS证书设置指南
极光官方文档-iOS SDK集成指南
iOS开发证书的名词解释
2018iOS极光推送完整流程