didReceiveRemoteNotification:fetchCompletionHandler:从图标与推送通知打开

我试图实现后台推送通知处理,但我有问题,以确定是否用户打开从推送通知,而不是从图标打开它的推送通知的应用程序。

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { //************************************************************ // I only want this called if the user opened from swiping the push notification. // Otherwise I just want to update the local model //************************************************************ if(applicationState != UIApplicationStateActive) { MPOOpenViewController *openVc = [[MPOOpenViewController alloc] init]; [self.navigationController pushViewController:openVc animated:NO]; } else { ///Update local model } completionHandler(UIBackgroundFetchResultNewData); } 

有了这个代码,无论用户如何打开应用程序,应用程序都可以打开到MPOOpenViewController。 我怎样才能使视图控制器只有当他们打开应用程序刷新通知推送?

使用相同的代码,这工作在iOS 6,但与新的iOS 7方法,它不performance我想要它。

编辑:我想现在在iOS 7上运行的应用程序,我们不支持iOS 7之前的任何版本。我在方法(没有完成处理程序)的iOS 6版本中使用相同的确切代码,它performance我期望的方式。 你会刷通知,这将被调用。 如果你从图标打开,该方法永远不会被调用。

好的,我明白了。 该方法实际上被称为两次(一次当它接收推,一次当用户与图标或通知交互)。

 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { if(application.applicationState == UIApplicationStateInactive) { NSLog(@"Inactive"); //Show the view with the content of the push completionHandler(UIBackgroundFetchResultNewData); } else if (application.applicationState == UIApplicationStateBackground) { NSLog(@"Background"); //Refresh the local model completionHandler(UIBackgroundFetchResultNewData); } else { NSLog(@"Active"); //Show an in-app banner completionHandler(UIBackgroundFetchResultNewData); } } 

感谢Tim Castelijns做了以下补充:

注意:被调用两次的原因是由于Payload具有content_available : 1 。 如果你删除了键和它的值,那么它只会在点击时运行。 这不会解决所有人的问题,因为有些人需要这个关键是真实的

@ Swift 2中MikeV的解决scheme:

 func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) { if(application.applicationState == UIApplicationState.Inactive) { print("Inactive") //Show the view with the content of the push completionHandler(.NewData) }else if (application.applicationState == UIApplicationState.Background){ print("Background") //Refresh the local model completionHandler(.NewData) }else{ print("Active") //Show an in-app banner completionHandler(.NewData) } } 

在Swift 3中MikeV的解决scheme(但是使用switch语句):

 func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { switch application.applicationState { case .inactive: print("Inactive") //Show the view with the content of the push completionHandler(.newData) case .background: print("Background") //Refresh the local model completionHandler(.newData) case .active: print("Active") //Show an in-app banner completionHandler(.newData) } }