iOS:尽可能保持与外部BLE设备的连接

在arkulpa,我们为客户构建了一个应用程序-在初始设置后-必须尽可能保持与外部BLE设备的连接,而无需用户做任何事情。 BLE设备是一种家庭配件,其目标是,如果用户离开房屋并可能在几天或几周后才返回,则应自动重新建立连接。

有关iOS / Swift / BLE的详细介绍,请转到此非常棒的博客文章(三部分)。 本文可以看作是扩展,重点是使蓝牙连接保持活动状态,并包括Apple开发人员技术支持提供的一些响应。

学习#1

如果您想在后台运行应用程序时找到BLE设备,请不要在此处使用所有nil

  centralManager.scanForPeripherals(withServices:无,选项:无) 
  pheral.discoverServices(无) 
  pheral.discoverCharacteristics(nil,用于:服务) 

根据Apple文档:

指定了bluetooth-central背景模式的应用程序可以在后台扫描。 也就是说,它们必须通过在serviceUUIDs参数中指定它们来显式扫描一个或多个服务。 在CBCentralManager扫描时,将忽略CBCentralManager扫描选项。

因此,我们要做的是在设置过程中使用nil选项进行扫描(= app位于前台),然后保存所有UUIDs (例如,在UserDefaults )。 当我们需要在应用程序处于后台运行时进行扫描时,我们可以使用保存的UUID。

学习#2

我们需要一种方法来使应用程序在连接断开时自动在后台自动重新连接,大多数情况下,这是因为iPhone和BLE之间的距离太大。 事实证明,这很简单(尽管您必须知道):只需在func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?)再次调用connect -method func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?)因为…

[…]连接请求不会超时,用户返回家园时,iOS设备将重新连接。

问题是:只有在以下任何一种情况下,它才起作用:

  1. 设备重启
  2. 蓝牙无线电正在关闭然后重新打开
  3. 飞行模式开启然后关闭
  4. 如果由于某种原因BLE堆栈崩溃
  5. 而且,最重要的是,用户强制退出了您的应用

(引自Apple Developer技术支持的邮件)。 尽管“重新连接”解决方案对我来说总是适用于2.)和3.),但是仍然存在无法重新建立连接的其他用例。 这导致我们……

学习#3

我们正在寻找一种解决方案,以在后台唤醒应用程序并重新建立连接。 我们发现,是将iBeacon与BLE设备结合在一起,其中iBeacon负责唤醒设备,因为据Apple称(再次,开发人员技术支持):

在用户强制退出应用后,可以使用的服务很少,可以重新启动您的应用。 区域监视就是其中之一。

[…]

是的,Region Monitoring将唤醒该应用程序,并在必要时重新启动它,并为您提供10秒钟的时间来完成您需要做的事情。

您可以将其与您提到的状态恢复方案结合起来,这将有足够的时间来设置BLE东西,并在BLE端连接时让系统再次唤醒您。

另外,您可以使用https://developer.apple.com/reference/uikit/uiapplication/1623031-beginbackgroundtaskwithexpiratio将这10秒延长到180秒,但这会增加更多的复杂性,而且我相信您不需要那么多时间。

如果您的BLE设备正确且快速地投放广告,则您应该能够在10秒内进行扫描,发现和连接。

但这还不够:仅在广告iBeacon旁边放置iPhone不足以唤醒它-仅enterexit事件才能唤醒该应用程序。 因此,我们与硬件部门一起做的就是以仅在连接BLE时发布的方式实施iBeacon。 因此,当用户退出应用程序时,BLE连接丢失(并且由于上面的#5而无法重新连接),iBeacon再次开始发送。 现在我们的应用程序获取

  func locationManager(_管理器:CLLocationManager,didEnterRegion区域:CLRegion) 

方法调用,可以重新建立与BLE设备的连接。

学习#4

这个并不是真的专门针对保持连接,而是花费了一些时间: 永远不要将硬编码的pheral.identifier存储在应用程序中,甚至不进行测试。 我们正是这样做的:只是发现在另一台设备上进行测试后,我们突然发现查找外围设备时遇到了问题(即无法找到它)。 原因 :生成了UUID并隐藏了MAC地址,因此,扫描同一外围设备的不同iOS设备会为同一外围设备生成不同的UUID。

尽管您需要了解自己在做什么以及如何工作,但使用BLE确实很有趣。 但是,一旦您将所有部件组合在一起,就会获得真正超棒的功能!