即使“plist”中的“UIBackgroundModes”中存在“voip”,iOS 应用程序在 iOS10 中设备重启后也不会自动启动
Posted
技术标签:
【中文标题】即使“plist”中的“UIBackgroundModes”中存在“voip”,iOS 应用程序在 iOS10 中设备重启后也不会自动启动【英文标题】:Even with "voip" present in "UIBackgroundModes" in "plist", iOS App does not auto start after device reboot in iOS10 【发布时间】:2017-03-30 07:29:07 【问题描述】:我需要我的 VoIP 应用在重启设备后自动启动。
Apple 文档明确提到:-
(=========编辑:这是来自苹果官方文档,请在评论或回答没有用户交互或静默推送通知的情况下无法启动应用程序之前先看看这个。还有看看下面的 Github 项目,人们已经验证了这种行为)
UIBackgroundModes 数组的值
价值:voip 描述:该应用程序提供IP语音服务。 具有此键的应用会在系统启动后自动启动所以 该应用程序可以重新建立 VoIP 服务。具有此密钥的应用程序是 还允许播放背景音频。
https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/iPhoneOSKeys.html#//apple_ref/doc/uid/TP40009252-SW1
我已确保:-
-
设备关机时应用正在运行。
VoIP 出现在
plist
和Capabilities
部分。
通过在main
方法和application:didFinishLaunchingWithOptions:
方法中将日志添加到文件中,确保应用程序在设备重启后肯定不会启动。
在设备重新启动后,设备的屏幕至少会解锁一次。
我什至尝试执行这个 GitHub 示例应用程序,获得 36 颗星来测试 启动启动。 https://github.com/lithium3141/BootLaunch 但是,当我在设备上尝试时,即使是这个应用程序也不会在重启时重新启动。
因此,这让我想到 iOS10 最近是否发生了某些变化,或者我仍然在这里遗漏了什么?
【问题讨论】:
如果不点击应用图标或接收推送工具包有效负载,您的应用将永远不会被自动撤销。如果您希望您的应用程序是基于 VOIP 的,并且应用程序在设备重启后被撤销。不可能。 @Hasya 我承认您的回答以及您的上述评论。但我在问题中提到了 Apple Doc 链接。苹果表示可以做到。如果您还打开我在问题中提供的 Github 链接,您会看到开发人员已经尝试并承认这是可能的。 ios需要外部用户交互事件或payload接收事件,否则不会触发应用执行周期。 您如何确保您的应用在设备重启时没有运行?请注意,查看任务管理器可能不是决定性的!我建议记录,甚至可以在相应的方法中为此创建一个文件。另一种方法是在 Xcode 的“Debug - Attach to process...”菜单中检查进程列表。我还发现了这个:forums.developer.apple.com/thread/44939,所以也许你的代码中的某些东西在初始化你的 voip 监听器时不起作用?现在只是进一步调试的想法,希望它至少有所帮助。另外:哇,有多少人不明白你的问题...... @Gero 感谢您的回复。是的,在这种情况下,应用程序在多任务 UI 中的存在是无关紧要的。该 UI 显示最近启动的应用程序列表,与正在运行的应用程序无关。我还通过将日志添加到文件来进行检查。在“main”文件和“application:didFinishLaunchingWithOptions:”方法中都不会触发应用程序的日志。这表明应用程序在重新启动后没有启动。 【参考方案1】:好的,我对此进行了更深入的调查,但首先我应该指出,我并没有通过实际尝试为此构建一个项目来验证这一点,因为这对我来说太耗时了。
我找到了this(已在 cmets 中提到)、this,最重要的是this tech Q&A。
我从这些线程中特别是 Apple 技术人员的各种 cmet 中收集到的信息,似乎 iOS 10 的行为确实发生了变化。这意味着如果您将构建链接到最新的 SDK(即 iOS 10 库),则在过去版本的 iOS 中连接到 VoiP 服务器的相同代码将不再执行此操作。
现在,就您而言,您实际上并不需要真正的 VoiP 连接,对吧?您只是对“重启后启动”功能感兴趣,对吗?至少您链接的演示项目实际上并没有进行任何 VoiP 连接,例如,setKeepAliveTimeout:handler:
方法甚至没有实现。
我知道这个特定问题没有在链接的线程中讨论或在问答中解决,但是:
有道理的是,连同整个传统的 VoiP 行为,重启功能也消失了。如果您切换到 Push-Kit VoiP,则您的应用无需在重新启动后启动,它会在下一个远程通知到达时重新启动(并且 VoiP 通知具有高优先级,因此应该没有延迟)。
显然,我在这里推断了整个事情背后的基本原理,并且不能保证 Apple 真的按照这些思路思考,但这是有道理的:(旧版)VoiP 应用程序在经过一段时间后(重新)启动的全部原因reboot 是它需要建立连接,即它需要运行一些代码。由于不再需要推送通知(操作系统基本上会在幕后为您完成这些操作以获取这些通知),因此他们完全删除了此功能以及整个旧版 VoiP 方法是有道理的。
您可以通过针对较旧的 SDK 进行编译来测试这一点(即按照问答建议使用 Xcode 7),然后查看它是否会重新启动。一位苹果员工实际上解释说,操作系统确实区分了应用程序的构建 SDK,这对我来说完全违反直觉。显然在这种情况下,它会决定“嘿,这是一个较旧的应用程序,因此它希望重新启动,因为它的 SDK 是以这种方式记录的”,用于构建在 Xcode 7 上的应用程序和“哦,这个应用程序是一个新应用程序,所以我不否则就不需要坚持旧方法。哇塞。
TL;DR:在我看来,是的,iOS SDK 改变了这种行为,同时放弃了整个旧的、无通知的 VoiP 方法。针对新的 SDK 进行编译将导致应用在重启后无法重新启动。
记录在案:我能理解那些帖子里愤怒的人。虽然这种变化可能有技术原因,但这种具体后果远非显而易见。如果某个方法已被弃用,但该项目仍然可以编译并运行,我不希望这样的过程以这种方式失败。这些应用程序不会崩溃,它们只是“被操作系统区别对待”,这并不完全相同。至少我希望文档在新 SDK 中更清楚地说明这一点。
【讨论】:
谢谢。尽管我从您之前的评论中得到了暗示,该行为可能已在 XCode8/iOS10SDK 中停止。这应该通过在 XCode7 上针对 iOS9SDK 进行编译来验证,但线程让它很清楚。此外,从 macOS Sierra 降级到 XCode7 的 ElCapitan,只是为了验证这种行为,需要付出很多努力。相反,由于该框架已被弃用,最好继续前进并寻找最佳替代方法(Push Kit)。【参考方案2】:当应用程序处于终止模式时,它会在后台调用,只有推送工具包静默通知并且必须为推送工具包生成证书,而不是正常的 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
// 如果您有操作按钮(远程),则处理方法
注意 - 如果不点击应用程序图标或接收推送工具包负载,您的应用程序将永远不会自动被撤销/打开/repoen。如果您希望您的应用程序是基于 VOIP 的,并且应用程序在设备重启后被撤销。不可能。
【讨论】:
感谢您的回复。我已经知道静默 APNS 方法。但是,如果您参考我在回答中给出的 Apple Docs 链接和 Github 项目,很明显 VoIP 应用程序确实在重新启动时被唤醒,如果它们在设备重新启动之前运行的话。这就是我想要弄清楚的。 重启意味着,你的设备不会重启,当你的应用程序被强制终止或关闭并且 pushkit 有效负载到达时,应用程序在后台调用 didFinishLaunchingWithOptions (这就是他们的意思重启)。 应用程序在设备关闭之前终止。但是,如果您检查 Apple 文档链接,VoIP 应用程序应该在重新启动时由操作系统启动。我知道静默 APNS 有效负载方法,但我不打算使用它,因为它不符合我的要求。 您可能已经提到了您上面所说的这一点,但我确信您的应用程序不会在设备重新启动时被撤销并且应用程序被终止。您最多可以做一件事,将您的 VOIP 频道详细信息保存在 NSUserDefault 中,并检查 didfinishlaunch 并继续进行进一步的通话。 这就是为什么我放了 GitHub 项目的链接和 Apple 文档的链接。如果您可以看一下,苹果文档明确指出“值:voip 描述:该应用程序提供 IP 语音服务。具有此密钥的应用程序会在系统启动后自动启动,以便该应用程序可以重新建立 VoIP 服务”以上是关于即使“plist”中的“UIBackgroundModes”中存在“voip”,iOS 应用程序在 iOS10 中设备重启后也不会自动启动的主要内容,如果未能解决你的问题,请参考以下文章
Xcode 项目浏览器未显示“GoogleService-Info.plist”,即使它位于目录中
即使我在 info.plist 中添加了 NSCameraUsageDescription,SwiftUI 应用程序也会崩溃
带有地理位置网站的 Flutter iOS webview 应用程序不会询问位置权限,即使 info.plist 已调整