【问题标题】:application:didReceiveRemoteNotification:fetchCompletionHandler Not Called应用程序:didReceiveRemoteNotification:fetchCompletionHandler 未调用
【发布时间】:2013-09-22 06:24:08
【问题描述】:

当应用程序被强制退出时,似乎没有调用函数application:didReceiveRemoteNotification:fetchCompletionHandler。我的印象是无论应用程序处于什么状态都会调用该函数,但似乎只有当应用程序已经在后台运行时才会调用它。如果应用程序尚未使用新的 iOS 7 远程通知后台模式运行,是否可以在后台唤醒应用程序?

【问题讨论】:

标签: ios objective-c ios7 apple-push-notifications


【解决方案1】:

根据 Apple 的说明,新的多任务 API(获取和远程通知)仅在应用处于 suspended/background/foreground 状态时才能工作。

  • background/foreground状态下,application:didReceiveRemoteNotification:fetchCompletionHandler会被触发。

  • Suspended 状态下,-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 将被触发。

  • Not Running 状态(您的情况)下,application:didReceiveRemoteNotification:fetchCompletionHandler 永远不会被触发。

有关应用状态的更多信息,请参阅Apple documentation

【讨论】:

  • "与 application:didReceiveRemoteNotification: 方法不同,该方法仅在您的应用程序运行时调用,无论您的应用程序处于何种状态,系统都会调用此方法。如果您的应用程序已暂停或未运行,则系统唤醒或启动您的应用程序并在调用该方法之前将其置于后台运行状态。”。你确定吗?
  • 如果应用程序处于“未运行”状态。远程通知永远不会唤醒应用程序。
  • 我同意 Luka 的评论。答案是不正确的。 application:didReceiveRemoteNotification:fetchCompletionHandler: 即使应用程序被挂起、根本没有运行或后台运行也会被调用。另外值得注意的是,上述方法仅适用于 iOS 7。
  • @Nandha 是的,我有。为了清楚起见,这里询问的方法是application:didReceiveRemoteNotification:fetchCompletionHandler:,这与application:didReceiveRemoteNotification:不同,这是第一种方法的apple documentation
  • 另外值得注意的是:当收到推送时,应用程序只有在“如果需要”时才会被唤醒以调用application:didReceiveRemoteNotification:fetchCompletionHandler: 方法。即在推送通知有效负载中,您必须设置“内容可用”标志(请参阅SO answer)。如果用户随后通过点击通知打开应用程序,该方法将被再次调用
【解决方案2】:

应用程序即使没有运行也应该启动。苹果文档说:

当此值存在并且推送通知到达设备时,系统会发送 向您的应用发出通知(在需要时启动它),并在向用户显示任何内容之前给它一些时间来处理 > 通知。 (iOS 应用编程指南)

当推送通知到达时,系统会向用户显示通知并 在后台启动应用程序(如果需要),以便它可以调用此方法。 (UIApplicationDelegate 协议参考)

与 application:didReceiveRemoteNotification: 方法不同,该方法仅在 您的应用程序正在运行,无论您的应用程序的状态如何,系统都会调用此方法。如果 您的应用暂停或未运行,系统唤醒或启动您的应用并放入 它在调用该方法之前进入后台运行状态。 (UIApplicationDelegate 协议参考)

但是,当使用 "content-available":1 推送测试时,应用在未运行时永远不会启动。当应用程序暂停时,它可以工作。

Wes 找到自己的解决方案了吗?

【讨论】:

  • @emiel:当我的应用程序被终止/暂停时,我需要你的帮助。现在我收到一个通知并将数据发送到服务器而无需打开应用程序。怎么可能或者 UIApplicationDelegate 协议参考的哪个方法调用
【解决方案3】:

如果您从应用程序切换器中强制退出应用程序,它不会在后台(通过任何方式)被唤醒,直到下一次启动之后。当您强制退出应用程序时,您实际上是在向操作系统表明您根本不希望该应用程序运行,即使后台事件通常会唤醒它。

这在测试期间值得注意,因为您可能已经强制退出应用程序以检查它是否在应用程序未运行时通过推送通知启动。事实上,您使用强制退出将是为什么它没有启动的原因。

【讨论】:

    【解决方案4】:

    当您的应用程序被强制退出时,不会调用该方法。而是像往常一样调用(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

    如果应用是通过在通知弹出窗口中点击“打开”打开的,则通知位于launchOptions 内。

    像这样获取推送通知字典:

    NSDictionary * pushNotificationUserInfo = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
    
    if (pushNotificationUserInfo)
    {
      // call your handler here
    }
    

    【讨论】:

      【解决方案5】:

      application:didReceiveRemoteNotification:fetchCompletionHandler: 被调用,即使应用程序被挂起、根本没有运行、后台运行或处于活动状态。另外值得注意的是,该方法仅适用于 iOS 7。这是apple documentation

      但是如果应用被强制关闭(即通过应用切换器杀死),应用将不会启动。(请参阅SO answer编辑: 我在 iOS 7.1 上再次检查了这个问题,看看他们是否修复了这个问题,但仍然存在如果应用程序被手动终止,应用程序将不会被唤醒并且application:didReceiveRemoteNotification:fetchCompletionHandler: 不会被唤醒的情况叫

      当接收到推送时,只有在“需要”时才会唤醒应用程序以调用application:didReceiveRemoteNotification:fetchCompletionHandler: 方法(即您必须在推送通知有效负载中设置“内容可用”标志。参见SO answer) .如果用户随后通过点击通知打开应用程序,该方法将被调用再次

      编辑:还没有在 iOS 8 上检查过。还有其他人吗?

      【讨论】:

      • 虽然说在应用程序根本不运行时会调用该方法似乎令人困惑,但如果应用程序被强制关闭则不会运行。那是另一个应用程序状态吗?
      • 这不是另一个应用程序状态,iOS 认为强制关闭应用程序是因为用户不希望该应用程序运行任何进程线程,直到它下一次启动。它正在按照 Apple 的意图工作,尽管他们的设计推理是有问题的
      • @nvrtd,“仅限 iOS 7”是指排除 iOS 8 吗?
      • 我刚刚在 iOS 8.4 上发现了这个问题。
      • iOS 9 需要 application:didReceiveRemoteNotification:fetchCompletionHandler:
      【解决方案6】:
      - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary
      *)launchOptions {
      
          //Remote Notification Info
          NSDictionary * remoteNotifiInfo = [launchOptions objectForKey: UIApplicationLaunchOptionsRemoteNotificationKey];
      
          //Accept push notification when app is not open
          if (remoteNotifiInfo) {
             [self application:application didReceiveRemoteNotification: remoteNotifiInfo];
          }
      
          return YES;
      }
      

      【讨论】:

      • -1,它不是强制退出的过程。上面的代码在用户通过点击通知按钮启动应用程序时运行。
      • 很好的答案真的应该被接受。
      • 这真的解决了问题!在application:didReceiveRemoteNotification:,我们“像往常一样”收到通知。
      【解决方案7】:

      在 Swift 2.0 中,我已经解决了我的问题,这是为了背景

      if let remoteNotification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? NSDictionary {
      
          pushNotificationAction(remoteNotification as [NSObject : AnyObject])
      }
      

      【讨论】:

        【解决方案8】:

        我最近遇到了同样的问题,我发现 Apple 更新了他们的文档并说:

        但是,如果用户强制退出应用,系统不会自动启动您的应用。在这种情况下,用户必须重新启动您的应用或重启设备,然后系统才会再次尝试自动启动您的应用。

        application(_:didReceiveRemoteNotification:fetchCompletionHandler:)

        所以我想当应用被强制退出时,没有办法做任何事情?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-06-03
          • 1970-01-01
          • 1970-01-01
          • 2014-04-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多