苹果的静默推送通知能否在后台启动我的应用程序?

5
根据苹果的文档,我可以通过在aps负载字典中添加“content-available”=1键值来注册静默通知。当静默通知到达时,我希望我的应用程序在后台唤醒。我将“App downloads content in response to push notifications”值设置为我的info.plist中的“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方法中接收回调。但我的问题是,当我们的应用程序处于被杀死状态时,我们能否获取到此或任何其他方法的回调?
我不希望我的应用用户看到通知,但我希望通过静默通知将其唤醒并在后台执行某些任务。
任何建议都将不胜感激。
2个回答

6
当设备接收到带有 content-available 设置的推送消息时,您的应用程序将由 Apple 在后台启动。用户不会意识到这一点。从文档中获取

content-available: 将此键提供一个值为 1,以指示新内容可用。包括此键和值意味着在后台启动或恢复应用程序时,将调用 -application:didReceiveRemoteNotification:fetchCompletionHandler:

还可以从 文档 中了解:

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


你说得没错,但问题是如果我的应用程序处于被杀死的状态并且收到了静默通知,那么我的应用程序将无法在后台启动。 - Vijay Sanghavi
你确定吗?这可能很难调试。如果你的Xcode调试技巧不是100%,那么在应用程序启动时编写日志文件可能是最容易的方法,这样即使没有附加到Xcode调试器也可以看到应用程序正在激活。该技术绝对有效,但有一些偶发问题 - TwoStraws
1
如果用户手动终止了您的应用程序,操作系统通常会将其视为用户真正不希望它运行的提示。在iOS中,确实有几个其他“后台”进程(例如使用NSURLSession进行后台文件传输)特别是不会像通常情况下那样启动您的应用程序,如果它已经从应用程序切换器中被杀死。我不知道这种特殊情况,但如果发现手动终止的应用程序在未被用户手动重新启动之前可能无法在推送通知上唤醒,那么这并不奇怪。 - Matt Gibson
1
@MattGibson 我正在按照您所说的做。我正在从应用程序切换器中终止我的应用程序,我实际想要的是即使用户杀死应用程序,也要在后台保持套接字连接,这就是我尝试在我的应用程序中使用静默通知的原因。就像如果设置了一段时间的静默通知,那么我可以在不知道用户的情况下唤醒我的应用程序在后台运行。 这可行吗?还是我走错了方向?或者有其他解决方案来解决我的问题吗? - Vijay Sanghavi
@TwoStraws 感谢您的建议,我一定会尝试使用 Xcode 调试器进行调试,并希望它能够正常工作。 - Vijay Sanghavi
4
根据这个现有回答的看法,我认为如果从应用程序切换器中杀死了一个应用程序,在收到通知时它不会被启动。这对我来说似乎是明智且用户友好的行为:如果我明确地终止了您的应用程序,我希望它保持停止状态。 - Matt Gibson

5

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

-(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,则可以知道您的应用程序已被唤醒。

注意:对我来说,这仅在后台模式下有效。如果我没有强制关闭(手动终止)我的应用程序,我会得到值,但是当我从应用程序切换器中强制关闭我的应用程序时,我将不会得到任何值。

希望这个解决方案能起作用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接