【问题标题】:Can Apple's silent push notifications launch my app in the background?Apple 的静默推送通知可以在后台启动我的应用程序吗?
【发布时间】:2016-03-21 08:21:58
【问题描述】:

根据 Apple 的文档,我可以通过在 aps 有效负载字典中添加 "content-available" = 1 键值来注册静默通知。我希望我的应用程序在静默通知到达时在后台唤醒。我在 info.plist 中将 App downloads content in response to push notifications 值设置为 Required background modes

这是我的有效负载字典

{"aps":
      {
       "alert":"Notification alert","badge":1,"sound":"default","content-available":1
      }
}

当我的应用程序在后台时,我在-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler 中收到回调。但我的问题是,当我们的应用程序处于终止状态时,我们可以回调此方法或任何其他方法吗?

我不希望我的应用用户看到通知,但我希望我的应用通过静默通知在后台唤醒它来执行某些任务。

任何建议将不胜感激。

【问题讨论】:

    标签: ios apple-push-notifications


    【解决方案1】:

    当设备收到设置了content-available 的推送消息时,Apple 会在后台启动您的应用。用户不会意识到这一点。 From the docs:

    content-available:为该键提供值 1 表示有新内容可用。包含此键和值意味着当您的应用在后台启动或恢复时,会调用-application:didReceiveRemoteNotification:fetchCompletionHandler:

    同样来自docs

    didReceiveRemoteNotification:但是,如果用户 已强制退出它。在这种情况下,用户必须重新启动您的应用 或在系统尝试启动您的应用程序之前重新启动设备 自动再次。

    【讨论】:

    • 你是对的,但问题是如果我的应用程序处于终止状态并且静默通知到达,而不是我的应用程序没有在后台启动。
    • 你确定吗?这可能很难调试。您可能会发现在启动应用程序时将日志写入文件是最简单的(如果您的 Xcode debug-fu 不是 100%),这样即使您没有使用Xcode 调试器。该技术确实有效,但there are some occasional quirks.
    • 如果您的应用程序已被用户手动终止,这通常被操作系统视为用户真的不希望它运行的提示。当然,iOS 中的其他几个“后台”进程(例如,使用 NSURLSession 进行后台文件传输)特别启动您的应用程序,如果它被应用程序切换器杀死,它们通常会这样做。我不知道这种特殊情况,但如果发现手动终止的应用程序在用户手动重新启动之前不会在推送通知上唤醒,我不会感到惊讶。
    • @MattGibson 我只是按照你所说的去做。我正在从应用程序切换器终止我的应用程序,我真正想要的是即使用户杀死应用程序也能在后台保持套接字连接,这就是我试图在我的应用程序中使用静默通知的原因。就像在一段时间内设置静默通知而不是在不知道用户的情况下我可以在后台唤醒我的应用程序一样。这可行吗?还是我走错了方向?或任何其他解决我的问题的方法?
    • this existing answer看来,我认为如果一个应用程序被应用切换器杀死,它在收到通知时不会启动它是正确的。对我来说,这似乎是明智的、用户友好的行为:如果我明确杀死你的应用,我希望它保持死态。
    【解决方案2】:

    我遇到过类似的情况,我编写了这段代码来调试我的应用程序是否在静默通知中唤醒。

    -(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
    {
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        NSString *str = [defaults objectForKey:@"key"];
        if (str  == nil) {
            str = @"didReceiveRemoteNotification";
        }else{
            str = [NSString stringWithFormat:@"%@, didReceiveRemoteNotification",str];
        }
        [defaults setObject:str forKey:@"key"];
        [defaults synchronize];
    }
    

    此代码的工作方式类似于,如果您的应用程序被唤醒,您将在此方法中获得回调,并且方法名称将写入 NSUserDefaults。所以当你手动调试你的应用程序时,你可以看到str字符串变量的值,如果有字符串didReceiveRemoteNotification,你就会知道你的应用程序已经唤醒了。

    注意:这仅适用于我的后台模式。当我没有强制关闭(手动终止)我的应用程序时,我获得了价值,但是当我从应用程序切换器强制关闭我的应用程序时,我不会获得任何价值。

    我希望这有效。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-03
      • 2018-01-23
      • 1970-01-01
      相关资源
      最近更新 更多