我通过使用推送通知上的内容可用标志来触发后台取回。我启用了取回和远程通知UIBackgroundModes。

这是我在我的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);

}

当应用程序在后台运行时,它工作得很好。(通知被接收,应用程序触发“看起来像我得到了一个通知”本地通知,正如上面的代码应该做的那样)。

但是,当应用程序没有运行,并且接收到带有content-available标志的推送通知时,应用程序不会启动,didRecieveRemoteNotification委托方法永远不会被调用。

WWDC视频《多任务处理有什么新发现》(2013年WWDC视频第204条)显示:

它说,当收到带有内容可用标志的推送通知时,应用程序将“启动到后台”。

为什么我的应用程序没有启动到后台?

所以真正的问题是:

用户强制退出应用后,iOS还会执行后台任务吗?


当前回答

这几天我一直在尝试不同的变体,我想有一天我让它在后台重新启动应用程序,甚至当用户滑动杀戮时,但我不能复制这种行为。

不幸的是,现在的行为与以前大不相同。在iOS 6上,如果你从晃动的图标中关闭应用程序,它仍然会在SLC触发器上被重新唤醒。现在,如果你通过滑动来杀人,就不会发生这种情况。

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

如果用户已经通过滑动关闭了应用,并且仍然期待着我们曾经提供给他们的一些通知行为,我们需要敦促他们重新打开应用。我担心当用户将应用移走时,这一点并不明显。毕竟,他们可能正在清理或想要重新排列显示为最小化的应用程序。

其他回答

实际上,如果你需要测试后台取回,你需要在scheme中启用一个选项:

另一种测试方法是:

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

这几天我一直在尝试不同的变体,我想有一天我让它在后台重新启动应用程序,甚至当用户滑动杀戮时,但我不能复制这种行为。

不幸的是,现在的行为与以前大不相同。在iOS 6上,如果你从晃动的图标中关闭应用程序,它仍然会在SLC触发器上被重新唤醒。现在,如果你通过滑动来杀人,就不会发生这种情况。

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

如果用户已经通过滑动关闭了应用,并且仍然期待着我们曾经提供给他们的一些通知行为,我们需要敦促他们重新打开应用。我担心当用户将应用移走时,这一点并不明显。毕竟,他们可能正在清理或想要重新排列显示为最小化的应用程序。

更新2:

你可以使用iOS 8中引入的新的PushKit框架来实现这一点。虽然PushKit用于VoIP。所以你的使用应该是VoIP相关的,否则有应用程序被拒绝的风险。(请看这个答案)。


UDPDATE1:

iOS8的文档已经澄清。文档可以在这里阅读。以下是相关节选:

Use this method to process incoming remote notifications for your app. Unlike the application:didReceiveRemoteNotification: method, which is called only when your app is running in the foreground, the system calls this method when your app is running in the foreground or background. In addition, if you enabled the remote notifications background mode, the system launches your app (or wakes it from the suspended state) and puts it in the background state when a push notification arrives. However, the system does not automatically launch your app if the user has force-quit it. In that situation, the user must relaunch your app or restart the device before the system attempts to launch your app automatically again.


虽然在WWDC的视频中没有明确说明这一点,但在开发者论坛上快速搜索就可以找到:

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

也要记住,如果你从应用切换器中杀死你的应用 (即向上滑动杀死应用程序),那么操作系统将永远不会重新启动 应用程序,无论推送通知或后台获取。在这种情况下 用户必须手动重新启动应用程序一次,然后从那开始 指出将被调用的后台活动。-pmarcos

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

因此,当应用程序从应用切换器中被杀死时(通过向上滑动),应用程序将永远不会启动,即使是预定的后台取回。

你可以在“管理方案”中更改目标的启动设置为等待<app>。这允许你通过在application: didReceiveRemoteNotification: fetchCompletionHandler:中设置一个断点来调试,并发送推送通知来触发后台启动。

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

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

综上所述,ios 8的新框架PushKit是一种新的推送通知机制,即使你的应用在应用切换器中被杀死,它也可以在后台无声地启动你的应用,没有任何视觉提醒提示,令人惊讶的是你甚至无法从应用切换器中看到它。

苹果的PushKit参考:

PushKit框架为你的iOS应用程序提供类 接收来自远程服务器的推送。push有两种类型: 标准和VoIP。标准推送也可以传递通知 在之前的iOS版本中。VoIP推送提供额外的 VoIP应用程序所需的标准推送功能之上 控件之前执行按需处理推送 通知用户。

要部署这个新功能,请参考本教程:https://zeropush.com/guide/guide-to-pushkit-and-voip -我已经在我的设备上测试了它,它可以正常工作。