最近的项目,需要对远程通知进行处理,首先我就不说那些配置证书的流程,以及一些的前期准备工作吧
首先我说下处理通知的三种情况。
一:app处于前台的时候收到远程通知;二:app处理与后台的时候收到通知;三:app退出了收到通知。这个三种情况,首先你得知道这三种情况下,app是如何处理的。
在第一种情况下:app收到远程通知会在appdelegate 中处理收到远程通知的。会直接调用这个方法
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
if (application.applicationState == UIApplicationStateActive) {
}
else if(application.applicationState == UIApplicationStateInactive)
{
}
completionHandler(UIBackgroundFetchResultNewData);
}
在这里处理收到远程通知的方法
在第二种情况下:app处于后台情况下收到远程通知,会在通知栏中显示通知的消息。当你点击通知中心的消息,app就会启动,然后会调用上面这个方法进行处理。
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
if (application.applicationState == UIApplicationStateActive) {
}
else if(application.applicationState == UIApplicationStateInactive)
{
}
completionHandler(UIBackgroundFetchResultNewData);
}
第三种情况:在app未启动的时候收到通知是这样处理的。当app未启动的时候,当收到远程通知的会在通知栏中显示。当你点击通知的时候,app就会启动,这样就得你手动去判断是否有通知,手动去调用收到通知如何处理的方法。注意当你app加载到homeViewController的时候在处理,不然的话会造成加载错误,处理不成功,那就需要延迟加载,延迟处理收到通知这个方法。下面这段代码是在AppDelegate中加的
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
/**
* 第一次启动时调用,判断是否有推送
*/
NSDictionary *notificationDict = [launchOptions valueForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if(notificationDict)
{
//有推送消息,处理推送的消息
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4* NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self application:application didReceiveRemoteNotification:notificationDict];
});
// [UMFeedback didReceiveRemoteNotification:notificationDict];
}
}
最近我们这个项目遇到个需求就是当App在前台的收到通知如何处理?需要在通知栏中显示。不能在收到通知在app前段有个弹框,这样就需要我们的就是讲收到的远程通知转换成本地通知。这种处理的方法就是将收到的通知转换成本地通知。这样的话就会在通知栏中显示。值得注意的就是我转换成本地通知连续发两条通知,当你下拉通知栏,通知消息就会消失,系统自动给你处理了,不会显示两条通知消息。
我是使用下面这个方法生成本地处理的
// 设置本地通知
- (void)registerLocalNotification:(NSInteger)alertTime
withDic:(NSDictionary*)userInfo
withBody:(NSString*)body{
UILocalNotification *notification = [[UILocalNotification alloc] init];
// 设置触发通知的时间
NSDate *fireDate = [NSDate dateWithTimeIntervalSinceNow:alertTime];
notification.fireDate = fireDate;
notification.repeatCalendar=[NSCalendar currentCalendar];
// 时区
notification.timeZone = [NSTimeZone defaultTimeZone];
// 设置重复的间隔
// ios8后,需要添加这个注册,才能得到授权
if ([[UIApplication sharedApplication] respondsToSelector:@selector(registerUserNotificationSettings:)]) {
// 通知重复提示的单位,可以是天、周、月
notification.repeatInterval = NSCalendarUnitDay;
} else {
// 通知重复提示的单位,可以是天、周、月
notification.repeatInterval = NSDayCalendarUnit;
}
// 通知参数
[notification setUserInfo: userInfo];
notification.alertBody = body;
notification.soundName = @"msg.caf";
// 执行通知注册
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
然后如果在前台收到通知,且转成本地通知,此时将app退出。如果这时将app退出的换点击通知的,启动app,那样的话就会丢失信息。因此我们需要像app未启动收到远程通知那样处理。这个是判断启动app是否收到本地通知
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UILocalNotification * notificationLocalDict = [launchOptions valueForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (notificationLocalDict!=nil) {
if (APPDELEGATE.viewController.JPushData == nil) {
[APPDELEGATE.viewController handleJPushData:notificationLocalDict.userInfo];
}
}
}
下面是处理当我们收到通知如何处理的重点内容。
首先我们收到通知,点击通知就会走到响应的页面中去,然后推出根据推送的内容,请求数据展示出来。这样就需要我们获取相应的页面知道在那跳转。在这三种情形下,是这样处理的。首先我们都是基于window的rootViewController,进行操作的,首先我们获取相应选中的tabbar selectIndex ,然后获取你的这个navController 的最后一个视图,在这个视图上present 或者push出来。这个说起来还是挺简单的。不说了,还是贴代码
-(void)toJpushDetail
{
id curViewController;
if (self.homeController!=nil) {
switch (self.homeController.tabBarController.selectedIndex) {
case 0:
curViewController = [self.homeController.homeVC.navigationController.viewControllers lastObject];
break;
case 1:
curViewController = [self.homeController.findMessageVC.navigationController.viewControllers lastObject];
break;
case 2:
curViewController = [self.homeController.myCenterVC.navigationController.viewControllers lastObject];
break;
default:
break;
}
}
if (curViewController!=nil) {
[self performSelector:@selector(toDetails:) withObject:curViewController afterDelay:0.5];
}
}