CBCentralManager是否连接超时?

我知道答案名义上是“不”,但我的意思是 –如果应用程序进入后台(启用​​BTLE后台处理),该怎么办? 24小时? 整个应用更新?

在“重新连接到外围设备”的标题下,此Apple文档描述了一个重新连接工作stream程,首先尝试重新连接到通过retrievePeripheralsWithIdentifiers:发现的先前配对的外围设备retrievePeripheralsWithIdentifiers:但是如果连接失败,则会再次开始扫描。 如果没有正式的超时,你怎么知道什么时候放弃connect到一个以前find的外设? 如果想要重新连接到之前发现的BTLE设备,那么如何在不需要用户与应用程序进行交互的情况下,如何知道何时开始/继续扫描?

此外,该页面的另一个说明指出,某些BTLE设备可能会在每次开机时为自己创build一个随机标识符,因此即使您从retrievePeripheralsWithIdentifiers:find以前配对的某些外围设备,也可能无法将其作为他们的名字已经改变。 是否有任何BTLE设备在实践中这样做? 那太疯狂了!

这是一个棘手的问题。 CoreBluetooth框架本身没有连接请求的正式超时。 实际上,它会尝试尽可能长的连接外设。 但是多久?

那么,不幸的是,这不是一个很好的定义。 当应用程序处于前台时,你可以非常确信连接不会超时,但是一旦涉及到后台连接,事情就不会再那么有趣了。 显然,就像你提到的那样,等待的连接将不会在手机重新启动后等。这是没有问题的,因为没有用户会希望应用程序在重新启动后仍然运行。 关于长时间运行挂起的连接,你会发现在苹果的文档中,他们告诉你select状态保存和恢复,以确保挂起的连接在应用程序被暂停并最终终止时被正确保存。 如果它能像广告一样工作,这将是一件好事,但不幸的是它不会。 经过多年的工作,我发现在iOS上获得可靠的后台连接几乎是不可能的。 我已经报告了这个话题的许多错误,但到目前为止还没有解决。

特别是有几个问题,我认为你应该特别注意:

  1. 如果在应用程序处于终止状态时发生蓝牙状态更改事件,状态保持和恢复将完全停止工作。 这基本上意味着,如果蓝牙芯片由于任何原因(例如,通过切换蓝牙/飞行模式等)而被重置,则当外围设备在范围内进行广告时,核心蓝牙将不再重新启动您的应用。 原因是因为你的应用程序设置的所有挂起的连接将被清除,只要蓝牙芯片重新启动。 这个问题是,你的应用程序将不会被重新启动通知这个变化,所以挂起的连接将永远不会被恢复。 所以你的应用程序会认为外设将连接,而事实上他们不会。 对我来说,这是最严重的问题,它使CoreBluetooth非常不可靠。

  2. 有时候,框架会陷入一种糟糕的状态(可能是由于内部竞争条件或类似的情况)。 这可能会随机发生,但通过在didFailToConnect或didDisconnectcallback中立即调用connectPeripheral,您可以非常容易地重现此操作。 发生这种情况时,“连接状态”属性设置为“正在连接”时,实际上未设置挂起的连接。 为了避免这种情况,我发现在连接之前至less应该等待大约20ms,例如使用dispatch_after或其他东西。

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

  4. 如果手表当前没有连接(超出范围/飞行模式/电池电量不足/或任何其他),则使用iPhone 7并同时拥有Apple Watch(配对手机)将彻底打破锁屏后的所有重新连接。原因)。 这是最近推出以来特别糟糕! 但由于某种原因,Apple Watch看起来比其他蓝牙外设“优先”。

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