最近的项目,须要对远程通知进行处理,首先我就不说那些配置证书的流程,以及一些的前期准备工做吧ios
首先我说下处理通知的三种状况。app
一:app处于前台的时候收到远程通知;二:app处理与后台的时候收到通知;三:app退出了收到通知。这个三种状况,首先你得知道这三种状况下,app是如何处理的。fetch
在第一种状况下:app收到远程通知会在appdelegate 中处理收到远程通知的。会直接调用这个方法spa
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { if (application.applicationState == UIApplicationStateActive) { } else if(application.applicationState == UIApplicationStateInactive) { } completionHandler(UIBackgroundFetchResultNewData); }
在这里处理收到远程通知的方法code
在第二种状况下:app处于后台状况下收到远程通知,会在通知栏中显示通知的消息。当你点击通知中心的消息,app就会启动,而后会调用上面这个方法进行处理。orm
-(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中加的get
- (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前段有个弹框,这样就须要咱们的就是讲收到的远程通知转换成本地通知。这种处理的方法就是将收到的通知转换成本地通知。这样的话就会在通知栏中显示。值得注意的就是我转换成本地通知连续发两条通知,当你下拉通知栏,通知消息就会消失,系统自动给你处理了,不会显示两条通知消息。it
我是使用下面这个方法生成本地处理的io
// 设置本地通知 - (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是否收到本地通知ast
- (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]; } }