最近的项目,需要对远程通知进行处理,首先我就不说那些配置证书的流程,以及一些的前期准备工作吧
首先我说下处理通知的三种情况。
一: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]; } }