最近想把自己写的极光推送遇到的一些问题列在这里,以便那些遇到推送问题的砖友们跳出这些坑,废话不多说,直接上代码:
第一步:当然是证书的问题,这里我就直接以开发证书为例,如果是生产证书,就直接自己再生成一个生产证书,搞成P12文件,提交到极光推送的控制台,需要注意的是,推送证书,开发证书,profile使用的证书必须一致,否则,你懂的。
注意,证书都搞定后,xcode工程里面的build phase一定要选择好对应的证书和profile,槽点就是如果你是正在开发中,就不要选择release的部分,选择了就收不到通知,另外就是profile必须选择最新的,还有就是capabilities中的通知以及Background Modes下的通知要打开,静态文件的cpu不支持模拟器cpu架构,所以必须真机才可以运行。
第二步,如何集成
注意:
1)当程序处于杀死状态时,收到通知,然后点击进入程序时,如果要进入指定界面,必须要在这里截取通知,进行判断后,直接跳转,上面代码的最下面;
第三步,都是常规写法:
//注册远程通知
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings{
[application registerForRemoteNotifications];
}
//获取deviceToken
- (void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
/// Required - 注册 DeviceToken
[JPUSHService registerDeviceToken:deviceToken];
NSLog(@"deviceToken:----%@",deviceToken);
}
//实现注册APNs失败接口
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
//Optional
NSLog(@"注册token失败:*****did Fail To Register For Remote Notifications With Error: %@", error);
}
注意:获取deviceToken失败的话,很大可能是证书的推送权限或者profile的问题,客户端网络的问题。
- (void)applicationWillEnterForeground:(UIApplication *)application {
//继续上传
// [self reStartUpload];
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
[application cancelAllLocalNotifications];
}
注意:程序进入前台时,要将应用图标的通知个数清零,同时,取消通知中心里面的通知。
#pragma mark- JPUSHRegisterDelegate
#ifdef NSFoundationVersionNumber_iOS_9_x_Max
#pragma mark- JPUSHRegisterDelegate
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler {
NSDictionary * userInfo = notification.request.content.userInfo;
UNNotificationRequest *request = 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; // 推送消息的标题
if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
[JPUSHService handleRemoteNotification:userInfo];
NSLog(@"iOS10 前台收到远程通知:%@", [self logDic:userInfo]);
[rootViewController addNotificationCount];
}
else {
// 判断为本地通知
NSLog(@"iOS10 前台收到本地通知:{\nbody:%@,\ntitle:%@,\nsubtitle:%@,\nbadge:%@,\nsound:%@,\nuserInfo:%@\n}",body,title,subtitle,badge,sound,userInfo);
}
completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert); // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以设置
}
- (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; // 推送消息的标题
if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
[JPUSHService handleRemoteNotification:userInfo];
NSLog(@"iOS10 收到远程通知:%@", [self logDic:userInfo]);
[rootViewController addNotificationCount];
}
else {
// 判断为本地通知
NSLog(@"iOS10 收到本地通知:{\nbody:%@,\ntitle:%@,\nsubtitle:%@,\nbadge:%@,\nsound:%@,\nuserInfo:%@\n}",body,title,subtitle,badge,sound,userInfo);
}
completionHandler(); // 系统要求执行这个方法
}
#endif
注意:这个直接复制进去,做好系统版本适配。
最后两个方法:
//当程序处于后台或者被杀死状态,收到远程通知后,当你进入程序时,就会调用
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
// Required, iOS 7 Support
[JPUSHService handleRemoteNotification:userInfo];
completionHandler(UIBackgroundFetchResultNewData);
NSDictionary *aps = [userInfo valueForKey:@"aps"];
// NSString *content = [aps valueForKey:@"alert"]; //推送显示的内容
// NSInteger badge = [[aps valueForKey:@"badge"] integerValue];
// NSString *sound = [aps valueForKey:@"sound"]; //播放的声音
// 取得自定义字段内容,userInfo就是后台返回的JSON数据,是一个字典
[JPUSHService handleRemoteNotification:userInfo];
application.applicationIconBadgeNumber = 0;
[self goToMssageViewControllerWith:userInfo];
NSLog(@"%@",userInfo);
}
//当程序正在运行时,收到远程推送,就会调用,如果两个方法都实现了,就只会调用上面的那个方法
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(@"尼玛的推送消息呢===%@",userInfo);
// 取得 APNs 标准信息内容,如果没需要可以不取
NSDictionary *aps = [userInfo valueForKey:@"aps"];
// NSString *content = [aps valueForKey:@"alert"]; //推送显示的内容
// NSInteger badge = [[aps valueForKey:@"badge"] integerValue];
// NSString *sound = [aps valueForKey:@"sound"]; //播放的声音
// 取得自定义字段内容,userInfo就是后台返回的JSON数据,是一个字典
[JPUSHService handleRemoteNotification:userInfo];
application.applicationIconBadgeNumber = 0;
[self goToMssageViewControllerWith:userInfo];
NSLog(@"%@",userInfo);
}
注意:- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
和(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
区别是,第一个是程序在后台或者杀死状态下,收到通知,进入前台时,会调用的方法
第二个是程序在前台运行时,收到通知会调用的方法,但是如果两个方法都存在,就只会走第一个方法,在这个方法里面进行业务逻辑,比如应用图标上的数字清零,获取到通知内容以及指定页面跳转。
// iOS 10 Support
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler {
// Required
NSDictionary * userInfo = notification.request.content.userInfo;
if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
[JPUSHService handleRemoteNotification:userInfo];
}
else {
// 本地通知
}
completionHandler(UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionSound|UNNotificationPresentationOptionAlert); // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以设置
}
还有几个小地方:
比如:plist文件设置UIBackground下的Modesremote-notification;
badge的设置,可以改变接受通知时的震动或是铃声提醒,也可以自定义提醒铃声;
另外,在前台要展示通知,目前只支持IOS10,IOS10以下的版本只会在后台或者程序处于杀死状态的时候才会展示。