#iOS最新极光推送实现细节以及对收到通知跳页面的处理
## 一、前言
推送对于APP来说是非常常见的功能,对于移动端开发的朋友来说肯定不会陌生,掌握它对于广大开发者来说是极其有必要的;今天我们介绍一下极光推送,关于apple通知的一些原理以及极光SDK的集成过程就不多做赘述了,按照极光的步骤几乎不会有什么问题。主要聊一聊收到消息之后的处理。
## 二、收到消息的来源
极光SDK集成之后,收到消息推送的时候分为3种情况,分别是:
1:APP在前台运行
2:APP进入后台(未结束进程)
3:APP未开启
## 三、对收到消息时不同情况的处理
对于不同的情况程序会进入不同的代理方法:
- APP在前台运行时:
```
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(NSInteger))completionHandler {
NSDictionary * userInfo = notification.request.content.userInfo;
self.notificationDic = [NSMutableDictionary dictionaryWithDictionary:userInfo];
[self dealNewNotifacation:[NSMutableDictionary dictionaryWithDictionary:userInfo]];//前台收到通知的处理,这里主要是处理数据源
if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
[JPUSHService handleRemoteNotification:userInfo];
}
completionHandler(UNNotificationPresentationOptionAlert); // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以选择设置
}
```
- APP进入后台(未结束进程)时:
```
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler{
NSDictionary * userInfo = response.notification.request.content.userInfo;
if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
[JPUSHService handleRemoteNotification:userInfo];
}
[JPUSHService setBadge:0];
self.notificationDic = [NSMutableDictionary dictionaryWithDictionary:userInfo];
[[NSNotificationCenter defaultCenter] postNotificationName:@"didReceiveJPushNotification" object:nil userInfo:self.notificationDic];
completionHandler(); // 系统要求执行这个方法
}
```
- APP未开启时(进程被杀死时):
```
此时可以通过- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions ;方法获取到消息内容,实现如下:
//获取推送消息
self.notificationDic = [launchOptions objectForKey:@"UIApplicationLaunchOptionsRemoteNotificationKey"];
if (self.notificationDic) {//通知消息不为空
[JPUSHService setBadge:0];//设置服务器上的badge为0
[[NSNotificationCenter defaultCenter] postNotificationName:@"didReceiveJPushNotification" object:nil userInfo:self.notificationDic];//发送通知
}
```
此时由于APP已经结束进程无法使用断点调试,也无法打印消息内容,建议把字典转成字符串,使用MBP/SVP等方式展示出来,(记得调试结束干掉测试代码);具体如下:
//[SlwySVProgressHUD showWithStatus:[SlwyCharacterToString dictionaryToJson:self.notificationDic]];
## 四、收到消息根据内容跳转到指定页面
细心的朋友肯定发现,在后台收到通知和应用程序未开启的情况下收到通知消息之后都发送了一个名为didReceiveJPushNotification的自定义通知,而在前台收到消息时仅仅只是调用了一个方法;
解释一下,由于我的项目需求是前台收到消息之后,只是保存数据到本地,其他两种情况都要求跳转到指定页面;所以在前台收到消息后仅仅只是做了数据处理和存储,其他两种情况到另外的地方处理(本项目结构是登录界面和tabbar装入了一个容器控制器中,所以需要在容器控制器中做逻辑处理,跳转页面);一般的Tabbar+Navigation的项目在APPDelegate.m就能实现。
好了,看看具体的收到通知消息的跳转吧,在二三种情况下啊,发送的通知会触发下面的方法:
```
/**
收到极光通知的处理
@param notification 通知内容
*/
- (void)didReceiveJPushNotification:(NSNotification *)notification {
if ([[self.childViewControllers firstObject] isKindOfClass:[SlwyTabBarViewController class]]) {//当前是tabbar
SlwyTabBarViewController *tabbar = [self.childViewControllers firstObject];
SlwyNvigaitionController *nav = tabbar.selectedViewController;//获取到当前视图的导航视图
NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithDictionary:notification.userInfo];
//BusinessLine:1.机票 / 2.酒店 / 3.火车票 / 4.专车 / 5.保险 / 6.贵宾厅服务
switch ([dic[@"BusinessLine"] integerValue]) {
case 1:{
SlwyApproPlaneDetailController *VC = [SlwyApproPlaneDetailController new];
VC.orderID = dic[@"OrderID"];
[nav.topViewController.navigationController pushViewController:VC animated:YES];//push到目的页面
}
break;
case 2:{
SlwyHotelOrderDetailViewController *VC = [SlwyHotelOrderDetailViewController new];
VC.orderID = dic[@"OrderID"];
[nav.topViewController.navigationController pushViewController:VC animated:YES];//push到目的页面
}
break;
case 3:{
SlwyMeTrainDetailController *VC = [SlwyMeTrainDetailController new];
VC.orderString = dic[@"OrderID"];
[nav.topViewController.navigationController pushViewController:VC animated:YES];//push到目的页面
}
break;
case 4:{
SlwyCarViewController *VC = [[SlwyCarViewController alloc]init];
VC.isFromOrderList = YES;
VC.orderID = dic[@"OrderID"];
[nav.topViewController.navigationController pushViewController:VC animated:YES];//push到目的页面
}
break;
default:
break;
}
dic[@"isRead"] = @"1";//设置该消息已读
[SlwyMyMessageModel dealMessageArray:dic];//处理收到通知
} else {//当前是登录
}
}
```
这里面最核心的就是取到navigationController,进行跳转,由于项目结构的不同我这里需要判断当前是否是加载的tabbar,一般的Tabbar+Navigation的项目直接在APPDelegate.m中拿到navigationController直接跳转即可。