核心蓝牙 – 在后台执行长期操作

这是来自官方文档中的iOS应用程序核心蓝牙后台处理部分:

在后台执行长期行动

某些应用程序可能需要使用Core Bluetooth框架在后台执行长期操作。 例如,假设您正在开发一款iOS设备的家庭安全应用程序,该应用程序与门锁(配备蓝牙低功耗技术)进行通信。 应用程序和锁相互作用,当用户离开家时自动锁住门,当用户返回时将其解锁 – 当应用程序在后台时。 当用户离开家时,iOS设备可能最终超出锁的范围,导致与锁的连接丢失。 此时,应用程序可以简单地调用CBCentralManager类的connectPeripheral:options:方法,并且因为连接请求不超时,所以iOS设备将在用户返回时重新连接。

好的,我们有一个应用程序,适当locking/解锁门…所以正如指出的,这是适用于应用程序在后台(最有可能在暂停模式)。 现在,让我们继续(引用文档):

现在想象一下用户离家几天。 如果应用程序在用户离开时被系统终止,则当用户返回家时应用程序将不能重新连接到锁,并且用户可能无法解锁门。 对于像这样的应用程序,能够继续使用核心蓝牙执行长期操作(例如监视活动连接和挂起连接)是至关重要的。

所以,如果用户离家几天,并且iOS终止了应用程序,我们将不得不实施状态保存和恢复,以便iOS在检测到连接请求时重新启动应用程序,并让应用程序打开门。 相关报价:

在上述家庭安全应用的情况下,系统将监控连接请求,并且当用户返回家庭并且连接请求完成时,重新启动应用以处理centralManager:didConnectPeripheral:委托callback。

这一切都是有道理的,但请注意这一部分:

现在想象一下用户离家几天。 如果应用程序在用户离开时被系统终止,则当用户返回家时应用程序将不能重新连接到锁,并且用户可能无法解锁门。 对于像这样的应用程序,能够继续使用Core蓝牙执行长期操作是至关重要的。

这是否意味着,如果应用程序在用户离开家的某个时刻被用户强行杀死,那么这也会起作用吗? 意思是当用户回家时,门会解锁,或者他必须手动重新启动应用程序来解锁门?

我在问这个问题,因为终止应用的重新启动是如何工作的。 当用户杀死应用程序,并且当iOS杀死支持后台执行的应用程序时,情况就不一样了:

支持后台执行的应用程序可能会被系统重新启动以处理传入的事件。 如果某个应用程序由于用户强制退出而被终止,系统将在下列事件之一发生时启动应用程序…

资源

所以再一次,如果用户离开了几天,他已经closures了应用程序的双击主页button,并拖动,他将能够进入他的家,而无需手动重新启动应用程序?

不。如果应用程序被用户强行杀死,那么它不会再被唤醒。 唯一一个会被唤醒的情况是,如果应用程序被iOS本身终止,这种情况迟早会发生,当时应用程序还没有成为前台的一段时间。 如果设备重新启动,它也不会重新启动。

话虽如此,从我的蓝牙芯片的经验,我得出的结论是国家保存是太不可靠了。 我相信你正在尝试实现的用例将不能很好地工作,这是非常具有讽刺意味的,因为这正是苹果推广它的文档的用例。

例如,您将遇到以下问题:

如果事件来自您正在与之通信的外设附件(如连接/断开连接事件和特征通知),状态恢复将只会因蓝牙相关的活动而重新启动您的应用程序。 对于其他事件,最重要的是一般的蓝牙状态改变事件,你的应用程序不会重新启动,并通知这个。 之所以这么糟糕,是因为任何蓝牙状态改变事件都会导致所有未决的连接被抛出,这意味着你挂起的门锁连接将会丢失。 但是,由于您的应用程序不会被重新启动,所以这实际上意味着您的应用程序仍然认为连接仍处于待定状态,而事实上它们并不是。 由于您的应用程序在此时被终止,所以再次唤醒的唯一方法是让用户再次手动启动它(或者为此目的“破解”其他后台模式,这也不会非常可靠地工作)。

这种情况下,如果用户切换飞行模式,切换蓝牙,重启iOS设备,或任何其他未定义的原因,许多导致状态的变化……并且这是不太可能的蓝牙状态改变不会发生,如果“…用户离家几天“。

这个“问题”已经被我和其他人多次报告,但是苹果似乎并不想因为某种原因来解决这个问题。

除此之外还存在很多其他的问题,如XPC连接在不同时间被中断,原因不明。 我也注意到挂起的连接可以进入“边缘”模式,其中外围状态被设置为连接,但事实上,除非循环连接状态,否则它将不会连接。 等等,…

/一个