背景:网上很多博文在说两个通知回调函数的区别时,就说两个方法是一样的,选其一即可,当时没多想。
//回调方法A:最早的方法
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo NS_AVAILABLE_IOS(3_0) __TVOS_PROHIBITED;
//回调方法B:7.0之后可用
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;
但是最近在开发app时,遇到一个问题,在程序完全关闭状态下(非后台状态),收到一个推送点击以后,想要跳转到一个页面。
于是按照以前的方法,在
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
方法里面写了处理,这个无需我多说。
然后为了在后台状态下也能跳转,在方法A中做了处理,这么写是没问题的,能正常实现功能。
但是后来随着7.0之前的系统被淘汰,于是把回调函数彻底换成了方法B。
结果发现一个问题,关闭状态下,点击通知,同样的界面入栈两次,也就是push了两次。一开始百思不得其解,后面开始各种猜测和调试:
过程1:实现方法A
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
[AlertView ShowTextHUD:@"didReceiveRemoteNotification" showInView:KEY_WINDOW];
//用UIAlertview输出didReceiveRemoteNotification
}
然后关闭程序,发送推送,点击,发现没有输出didReceiveRemoteNotification,验证了法A在程序关闭状态下点击推送体是不会进入的。
过程2:实现方法B
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler
{
[AlertView ShowTextHUD:@"didReceiveRemoteNotification" showInView:KEY_WINDOW];
//用UIAlertview输出didReceiveRemoteNotification
}
同样的测试方式,但是却输出了didReceiveRemoteNotification,说明就算关闭状态下点击通知,也是会走新的7.0以后的这个方法B
上述实验结果说明的事情一目了然了,结论就是,旧方法和新方法的区别除了新方法在7.0后才能用,且提供了一个completionHandler以外,还有一个很重要的区别:旧房法在完全关闭下点通知不调用,这时候处理通知得依赖didFinishLaunchingWithOptions来处理通知(也就是传统方法);但是新方法,就算在完全关闭状态下,点击通知也会调用,所以如果用了新方法,就绝不能在didFinishLaunchingWithOptions处理了,不然会处理两次,造成异常。