CBCentralManager连接是否超时?

时间:2016-11-24 10:18:23

标签: ios core-bluetooth btle

我知道答案名义上是"没有",但我的意思是真的 - 如果应用程序进入后台(启用​​了BTLE后台处理)会怎么样? 24小时?整个应用更新?

在标题"重新连接到外围设备"标题下,此Apple documentation描述了重新连接工作流程,该工作流程首先尝试重新连接到通过connect找到的先前配对的外围设备,但如果您再次开始扫描无法连接。如果没有正式超时,你怎么知道什么时候放弃retrievePeripheralsWithIdentifiers: - 以前找到的外围设备?你怎么知道什么时候开始/继续扫描,如果想要重新连接到以前找到的BTLE设备,只要你回到它附近,而用户不必与你的应用程序进行交互?

另外,该页面下方的一个注释表明,某些BTLE设备可能会在每次开机时为自己创建一个随机标识符,因此即使您找到{{1}}之前的一些先前配对的外围设备,您也可以因为他们的名字已经改变而无法连接到他们。任何BTLE设备在实践中都这样做吗?那是疯了!

1 个答案:

答案 0 :(得分:16)

这是一个难以回答的问题。 CoreBluetooth框架本身在连接请求上没有正式超时。事实上,它会尝试尽可能长时间地连接外设。但这有多长?

嗯,不幸的是,这不是一个非常明确的定义。当应用程序处于前台时,您可以非常确信连接不会超时,但只要您在后台处理连接,那么事情就不再那么有趣了。显然,就像你提到的那样,待机连接在手机重启后不会保留等等。这很好,因为没有用户会希望应用程序在重新启动后仍然运行。关于长时间运行的挂起连接,您将在Apple的文档中找到它们,它们会指示您选择加入状态保留和恢复,以确保在应用程序暂停并最终终止时正确保留挂起的连接。如果它像宣传的那样工作会很好,但不幸的是它没有。经过多年的努力,我发现在iOS上获得可靠的后台挂起连接几乎是不可能的。我已经报告了很多关于这个主题的错误,但到目前为止还没有解决。

我认为你应该特别注意一些问题:

  1. 如果在您的应用处于终止状态时发生蓝牙状态更改事件,则状态保留和恢复将完全停止工作。这实际上意味着如果蓝牙芯片因任何原因(例如切换蓝牙/飞行模式/等等)而被重置,那么只要外围设备在范围内进行广告宣传,您的应用就不会再被Core Bluetooth重新启动。这样做的原因是,每当蓝牙芯片重新启动时,您的应用程序设置的所有待处理连接都将被清除。这样做的问题是您的应用程序不会被重新启动以通知此更改,因此挂起的连接将永远不会被恢复。因此,您的应用程序会认为外围设备将连接,而事实上他们不会。对我而言,这是最严重的问题,仅此一点使得CoreBluetooth非常不可靠。

  2. 有时框架会“陷入”状态(可能是内部竞争条件或类似情况)。这可能是随机发生的,但您可以通过在didFailToConnect或didDisconnect回调中立即调用connectPeripheral来轻松地重现这一点。发生这种情况时,如果未设置挂起连接,则“连接状态”属性将设置为“连接”。为了避免这种情况,我发现你应该在连接之前至少等待大约20ms,例如使用dispatch_after或者什么。

  3. 框架内部使用XPC连接进行进程间通信,以便提供蓝牙事件。在某些情况下,无论出于何种原因,这都将破裂,并且连接将丢失。我不知道为什么会发生这种情况,但无论何时发生,状态保存都将停止工作,您将手动重新启动应用程序以从中恢复。有时我设法在设备sysdiagnose日志中捕获这个...

  4. 使用iPhone 7并同时拥有Apple Watch(与手机配对)将完全断开锁定屏幕后面的所有重新连接,以防Watch当前未连接(超出范围/飞行模式/电池电量不足/或任何其他原因)。这是特别糟糕的,因为它是最近推出的!但看起来Apple Watch出于某种原因比其他蓝牙外围设备具有“优先级”。

  5. 这些都是我的头脑,但也有其他问题。关于随机地址,通常这些外围设备使用所谓的“随机可解析”地址。这意味着它们看起来是随机的,但事实上它们可以使用IRK(身份解析密钥)来解决,IRK通常在初始蓝牙绑定期间共享。据我所知,使用完全随机地址的设备并不常见。