检测是否通过点击Notification Center中的通知调用application:didReceiveRemoteNotification:fetchCompletionHandler:

时间:2014-04-19 09:32:17

标签: ios cocoa-touch apple-push-notifications uiapplicationdelegate

application: didReceiveRemoteNotification: fetchCompletionHandler:

不同
application: didReceiveRemoteNotification:

如何?来自文档:

  

与应用程序不同:didReceiveRemoteNotification:方法,即   仅在应用程序运行时调用,系统才会调用此方法   无论你的应用程序状态如何。如果您的应用程序被暂停   运行,系统唤醒或启动您的应用程序并将其放入   调用方法之前的后台运行状态。 如果用户打开   您的应用程序从系统显示的警报中,系统调用此方法   再次,以便您知道用户选择了哪个通知。

我的奋斗是:我想知道用户是否通过通知中心点击系统显示的警报或者唤醒设备的静音推送通知来调用该方法。目前,据我所知,没有明显的区分方法。

- (BOOL)application: didFinishLaunchingWithOptions:

在上述方法中跟踪 launchOptions 不是解决方案,因为只有在应用程序暂停/未在后台运行时才会调用它。如果它在后台运行,则不会被调用。

8 个答案:

答案 0 :(得分:41)

Apple文档有点令人困惑

application: didReceiveRemoteNotification: fetchCompletionHandler:  
如果您的应用程序支持远程通知后台模式(即您正在进行BackgroundFetch),则使用

application: didReceiveRemoteNotification:  
当操作系统收到RemoteNotification且应用程序正在运行时(在后台/暂停或前台),将调用

。 您可以检查UIApplicationState以查看用户是否将应用程序置于前台(点击通知),或者在通知进入时是否已经运行。

- (void) application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
      UIApplicationState state = [application applicationState];
        // user tapped notification while app was in background
    if (state == UIApplicationStateInactive || state == UIApplicationStateBackground) {
         // go to screen relevant to Notification content
    } else {
         // App is in UIApplicationStateActive (running in foreground)
         // perhaps show an UIAlertView
    }
}

答案 1 :(得分:18)

您可以检查UIApplication的{​​{1}},以区分无声呼叫和用户正在使用的应用程序进行的呼叫:

applicationState

或者在typedef enum : NSInteger { UIApplicationStateActive, UIApplicationStateInactive, UIApplicationStateBackground } UIApplicationState; 的{​​{1}}上设置自己的旗帜。

答案 2 :(得分:9)

应用程序状态不可靠,因为如果您的应用程序打开了控制中心或Apple的通知中心,则应用程序:didReceiveRemoteNotification:fetchCompletionHandler:将被调用,应用程序状态将处于非活动状态。

我遇到同样的问题,试图在应用程序处于后台时响应点击通知,并且似乎没有可靠的方法来单独识别这一点。

答案 3 :(得分:3)

application: didReceiveRemoteNotification:fetchCompletionHandler:方法被调用时,如果用户点击警告(在这种情况下您想准备一些用户界面),则应用状态为UIApplicationStateInactive,当应用程序被静默唤醒时为UIApplicationStateBackground在这种情况下,您只需加载一些数据。)

答案 4 :(得分:2)

我不确定我是否理解你的问题。

您想要区分静音推送通知后台提取和嘈杂的推送通知吗?您只需检查推送通知字典是否包含“内容可用”密钥:[[userInfo objectForKey:@"aps"] objectForKey:@"content-available"]如果确实如此,则应该是静默推送。如果没有,这是正常推动。

您是否想知道当应用程序收到通知并且它处于挂起/未运行状态时是否调用了后台获取方法?如果是这样,您可以执行以下操作:

  • Download and import LumberJacks into your app.查看说明并了解如何设置,以便将日志保存到磁盘。
  • 将此问题放在您想要查看是否/何时调用该方法的任何方法中:

    • DDLogDebug(@"%@ - %@",NSStringFromSelector(_cmd),NSStringFromClass([self class]));

    这会将类和方法打印到日志文件中。

  • 在向您的后台启用应用程序发送推送通知后检查日志文件,并查看是否通过查看您的日志文件调用了任何方法。

如果您已正确设置应用以进行后台提取,则即使应用程序处于后台运行/未运行,如果您收到推送通知(无论是否无声推送),也会调用方法application: didReceiveRemoteNotification: fetchCompletionHandler:

答案 5 :(得分:2)

如果是swift

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {

    let state : UIApplicationState = application.applicationState
    if (state == .Inactive || state == .Background) {
        // go to screen relevant to Notification content
    } else {
        // App is in UIApplicationStateActive (running in foreground)
    }
}

答案 6 :(得分:1)

在iOS 10.0+中,您可以使用方法

- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler;

检测用户何时从NotificationCenter轻触系统显示的警报。

如果实现上述方法

    收到通知时,
  • - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult result))completionHandler;仅被称为
  • 用户点击通知时会调用
  • - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler;

答案 7 :(得分:0)

对于Swift:在application(_:didFinishLaunchingWithOptions:)中解析应用程序选项。如果它们存在,您就知道该应用程序是从它们中启动的。

  if let remoteNotif = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as? [String: Any] {
        print("Remote notfi is \(remoteNotif)")
        if let notification = remoteNotif["aps"] as? [AnyHashable : Any] {
        /// - parse notification
      }
  }

否则,您可以处理点按,并且您知道该应用已开启/后台/无效application(_:didReceiveRemoteNotification:fetchCompletionHandler:)