224

I am triggering a background fetch by using the content-available flag on a push notification. I have the fetch and remote-notification UIBackgroundModes enabled.

Here is the implementation I am using in my AppDelegate.m:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
    NSLog(@"Remote Notification Recieved");
    UILocalNotification *notification = [[UILocalNotification alloc] init];
    notification.alertBody =  @"Looks like i got a notification - fetch thingy";
    [application presentLocalNotificationNow:notification];
    completionHandler(UIBackgroundFetchResultNewData);

}

When the app is running in the background, it works fine. (The notification is received and the app triggered the "looks like i got a notification" local notification, as the code above should do).

However, when the app is not running and a push notification is received with the content-available flag, the app is not launched and the didRecieveRemoteNotification delegate method is never called.

The WWDC Video Whats New With Multitasking (#204 from WWDC 2013) shows this: enter image description here

It says that the application is "launched into background" when a push notification is received with the content-available flag.

Why is my app not launching into the background?

So the real question is:

Will iOS perform background tasks after the user has force-quit the app?

4

7 回答 7

217

更新2:

可以使用 iOS 8 中引入的新 PushKit 框架来实现这一点。尽管 PushKit 用于 VoIP。因此,您的使用应该与 VoIP 相关,否则存在应用被拒绝的风险。(见这个答案)。


UDPDATE1:

该文档已针对iOS8进行了澄清。可以在此处阅读文档。这是一个相关的摘录:

使用此方法为您的应用处理传入的远程通知。与application:didReceiveRemoteNotification:仅在您的应用程序在前台运行时调用的方法不同,系统在您的应用程序在前台或后台运行时调用此方法。此外,如果您启用了远程通知后台模式,系统会启动您的应用程序(或将其从挂起状态唤醒)并在推送通知到达时将其置于后台状态。但是,如果用户强制退出,系统不会自动启动您的应用程序。在这种情况下,用户必须重新启动您的应用程序或重新启动设备,然后系统才会再次尝试自动启动您的应用程序。


尽管 WWDC 视频没有明确说明这一点,但在开发者论坛上的快速搜索发现了这一点:

https://devforums.apple.com/message/873265#873265(需要登录)

另外请记住,如果您从应用切换器中终止您的应用(即向上滑动以终止该应用),那么无论推送通知或后台获取如何,操作系统都不会重新启动该应用。在这种情况下,用户必须手动重新启动应用程序一次,然后从那时起将调用后台活动。- pmarcos

那个帖子是由苹果员工写的,所以我认为我可以相信这些信息是正确的。

所以看起来当应用程序从应用程序切换器中被终止(通过向上滑动)时,应用程序将永远不会启动,即使对于预定的后台提取也是如此。

于 2013-10-05T20:38:58.730 回答
70

您可以在“管理方案”中将目标的启动设置更改为Wait for <app>.app to be launched manually,这样您就可以通过在其中设置断点application: didReceiveRemoteNotification: fetchCompletionHandler:并发送推送通知来触发后台启动来进行调试。

我不确定它是否能解决问题,但它现在可以帮助您进行调试。

截屏

于 2013-09-28T16:40:02.967 回答
38

答案是肯定的,但不应使用“后台获取”或“远程通知”。PushKit 是您想要的答案。

总而言之,iOS 8 中的新框架 PushKit 是一种新的推送通知机制,即使您的应用被从应用切换器中滑出,它也可以静默地将您的应用启动到后台而没有视觉警报提示,令人惊讶的是您甚至看不到它从应用切换器。

来自 Apple 的 PushKit 参考:

PushKit 框架为您的 iOS 应用程序提供类以接收来自远程服务器的推送。推送可以是以下两种类型之一:标准和 VoIP。标准推送可以像在以前的 iOS 版本中一样传递通知。VoIP 推送在标准推送之上提供附加功能,VoIP 应用程序在向用户显示通知之前执行推送的按需处理。

要部署此新功能,请参阅本教程:https ://zeropush.com/guide/guide-to-pushkit-and-voip - 我已经在我的设备上对其进行了测试,它可以按预期工作。

于 2015-03-24T11:26:18.727 回答
15

实际上,如果您需要测试后台获取,则需要在方案中启用一个选项:

启用 bg 获取

如何测试它的另一种方法: 模拟bg fetch

以下是有关此新功能的完整信息: http ://www.objc.io/issue-5/multitasking.html

于 2014-04-01T16:42:53.627 回答
4

几天来我一直在尝试不同的变体,我想了一天我让它在后台重新启动应用程序,即使用户滑动杀死,但我无法复制这种行为。

不幸的是,行为与以前完全不同。在 iOS 6 上,如果你从抖动的图标中终止了应用程序,它仍然会在 SLC 触发器上重新唤醒。现在,如果您通过滑动杀死,那不会发生。

这是一种不同的行为,如果用户在 iOS 6 上杀死了我们的应用程序,他们将继续从我们的应用程序中获取有用的信息,但现在不会了。

如果他们已经刷过应用程序并仍然期待我们过去提供给他们的一些通知行为,我们需要提醒我们的用户现在重新打开应用程序。我担心当用户滑动应用程序时,这对用户来说并不明显。毕竟,他们可能基本上是在清理或想要重新排列显示为最小化的应用程序。

于 2013-10-18T23:03:55.663 回答
3

这可能会帮助你

在大多数情况下,系统不会在用户强制退出后重新启动应用程序。一个例外是定位应用程序,它在 iOS 8 及更高版本中在被用户强制退出后会重新启动。但是,在其他情况下,用户必须明确启动应用程序或重新启动设备,然后系统才能将应用程序自动启动到后台。在设备上启用密码保护时,系统不会在用户首次解锁设备之前在后台启动应用程序。

来源: https ://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html

于 2018-04-05T10:04:07.613 回答
3

对于iOS13

iOS13后台推送需要设置以下参数:

apns-priority = 5
apns-push-type = background
//Required for WatchOS
//Highly recommended for Other platforms 

背景推动 视频链接:https ://developer.apple.com/videos/play/wwdc2019/707/

于 2019-08-20T04:41:34.517 回答