即使在 "plist" 中的 "UIBackgroundModes" 中存在 "voip",iOS 应用程序在 iOS10 中设备重启后也不会自动启动

Even with "voip" present in "UIBackgroundModes" in "plist", iOS App does not auto start after device reboot in iOS10

我需要我的 VoIP 应用程序在重启设备后自动启动。

Apple 文档明确提到:-

(=========编辑:这是来自 Apple 官方文档,请在评论或回答没有用户交互或无提示推送的情况下无法启动应用程序之前查看此内容通知。另请查看下面的 Github 项目,人们已经验证了此行为)

Values for the UIBackgroundModes array

Value : voip Description : The app provides Voice-over-IP services. Apps with this key are automatically launched after system boot so that the app can reestablish VoIP services. Apps with this key are also allowed to play background audio.

https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html#//apple_ref/doc/uid/TP40009252-SW1

我已经确保:-

  1. 应用程序在设备关机时运行。
  2. VoIP 出现在 plistCapabilities 部分。
  3. 通过在 main 方法和 application:didFinishLaunchingWithOptions: 方法中将日志添加到文件中,确保应用程序在设备重启后不会启动。
  4. 设备屏幕至少解锁一次,在设备重启后。

I even tried executing this GitHub example App with 36 stars to test Boot Launch. https://github.com/lithium3141/BootLaunch
But even this App does not restart on reboot when I tried on device.

因此,这让我想到 iOS10 中是否最近发生了一些变化,或者我是否仍然遗漏了什么?

当处于终止模式时,应用程序将在后台调用,仅使用推送套件静默通知并且必须为推送套件生成证书,而不是使用普通 APNS 通知和普通推送通知证书。

从后端来看,您的负载必须是这样的。

$body['aps'] = array(
'content-available'=> 1,
'alert' => $message,
'sound' => 'default',
'badge' => 0,
);

一旦你获得 pushkit 有效负载,然后安排带有声音文件的本地通知,你的应用程序将在后台调用直到你的声音文件播放。(最多 30 秒)然后你必须完成你的后台任务。

请参考有关推送套件集成的一些重要细节,逐步进行

https://github.com/hasyapanchasara/PushKit_SilentPushNotification

应用程序的生命周期 - 当应用程序终止并且推送套件有效负载到来时

  • 首先

    didFinishLaunchingWithOptions // 将调用

  • 然后

    didReceiveIncomingPushWithPayload // 有效载荷方法被调用

  • 那么如果你有本地通知

    didReceiveLocalNotification // 接收本地通知

  • 然后

    handleActionWithIdentifier // 如果你有操作按钮(本地)的处理方法

  • 那么如果你有远程通知

    didReceiveRemoteNotification // 接收远程通知

  • 然后

    handleActionWithIdentifier // 如果你有操作按钮(远程)的处理方法

注意 - 如果不点击应用图标或接收推送工具包负载,您的应用将永远不会自动获取 revoke/open/repoen。如果您希望您的应用程序基于 VOIP,并且应用程序在设备重启后被撤销。不可能。

好的,我对此进行了进一步调查,但首先我应该指出,我并没有通过实际尝试为此构建一个项目来验证这一点,因为现在这对我来说太耗时了。

我找到了 this (already mentioned in the comments), this, and most importantly this tech Q&A

我从这些线程中的 Apple 技术人员的各种评论中收集到的信息表明 iOS 10 的行为确实发生了变化。这意味着如果您 link 您的构建是针对最新的 SDK,即 iOS 10 个库,那么在 iOS 的过去版本中连接到 VoiP 服务器的相同代码将不再执行此操作。

现在,在您的情况下,您实际上不需要真正的 VoiP 连接,对吗?您只是对 "start after reboot" 功能感兴趣,对吗?至少您 linked 的演示项目实际上没有进行任何 VoiP 连接,例如 setKeepAliveTimeout:handler: 方法甚至没有实现。 我知道这个具体问题没有在 linked 线程中讨论或在问答中解决,但是:

有意义的是,连同整个旧版 VoiP 行为,重启功能也消失了。如果您切换到 Push-Kit VoiP,您的应用程序不需要在重新启动后启动,它会在下一个远程通知到达时重新启动(并且 VoiP 通知具有高优先级,因此应该没有延迟)。

显然,我在这里推导了这整件事背后的基本原理,不能保证苹果真的按照这些思路思考,但这是有道理的:(重新)启动(重新)启动(旧版)VoiP 应用程序的全部原因重启后 需要建立连接 ,即它需要 运行 一些代码。使用不再需要的推送通知(OS 基本上是在幕后为您完成这些操作以获取这些通知),因此他们完全删除此功能以及整个遗留 VoiP 方法是有道理的。

您可以通过针对较旧的 SDK 进行编译(即按照问答建议使用 Xcode 7)来测试它,然后查看它是否会重新启动。一位苹果员工实际上解释说 OS 确实区分了应用程序的构建 SDK,这对我来说完全违反直觉。显然在这种情况下,它将决定 "hey, this is an older app, so it expects to be relaunched cause its SDK was documented that way" 用于在 Xcode 7 上构建的应用程序,否则 "Oh, this app is a new one, so I don't need to stick to the old ways"。哇塞.


TL;DR:对我来说,它非常像是的,iOS SDK 改变了这种行为,同时放弃了整个旧的、无通知的 VoiP 方法。针对新 SDK 进行编译将导致应用程序在重启后不会重新启动。

备案:我能理解那些帖子里愤怒的人。虽然这种变化可能有技术原因,但这种具体后果远非显而易见。如果一个方法被弃用,但项目仍然编译并且 运行s 我不希望这样的过程以那种方式失败。这些应用程序不会崩溃,它们只是 "treated differently by the OS",不太一样。至少我原以为新 SDK 中的文档会更清楚这一点。