我有一个用例,其中有两个设备。一个是运行IOS应用程序的苹果手机,另一个是启用BLE的物联网设备。
- IOS应用程序持续扫描附近的BLE设备,如果它发现一个具有特定UUID服务的ABL设备,它将连接到它并通过GATT特征发送数据
- 此IOS应用程序即使在后台也应连续运行。也就是说,当它在后台时,它应该扫描具有特定服务的BLE设备,如果找到它,它应该在后台连接到它并写入GATT特征
- 这里的问题是IOS在应用程序处于后台时终止应用程序
- 唯一的方法是使物联网设备广播IBeacon而不是普通的BLE信标。但是如果找到IBeacon,IOS应用程序将在后台被唤醒,但它无法获得发送IBeacon的设备的BLE地址,也无法连接到它
如何解决此问题?
虽然iBeacon在后台检测速度很快,效果最好,但这并不是绝对必要的。您可以在后台检测iOS上的BLE服务,并在发现它时连接到它。
要做到这一点,您必须:
- 在Info.plist中声明:
<key>UIBackgroundModes</key>
<array>
<string>bluetooth-central</string>
</array>
- 在
didFinishLaunching
中的AppDelegate中,您必须触发BLE扫描启动
centralManager?.scanForPeripherals(withServices: [myServiceUUID], options: nil)
如果您执行上述操作,则在应用程序终止后,iOS将自动启动您的应用程序,并且当发现新的外围设备时,您将获得对didDiscoverPeripheral
的回调。
虽然这确实有效,但由于iOS跟踪重复项的方式,很难正确测试。如果一个设备已经被检测到,并且你杀死了你的应用程序,你将不会得到关于其发现的回调——iOS会跟踪它已经被检测。它只会给你一个新设备的启动和回调。
以下是我测试它的方法:
- 修改您的应用程序,以便在检测到BLE设备时发送本地通知。验证这个工作
- 关闭BLE设备
- 启动你的应用程序
- 重新启动手机
- 打开BLE设备
- 等待上面的通知。耐心点!当您重新启动手机时,BLE堆栈可能会在几分钟内无法完全启动
上面的手机重新启动步骤对于清除iPhone已经看到的设备的缓存至关重要,因此不符合回调条件。
最后,您可以使用BLE设备来加速这一过程,该设备还宣传iBeacon,因为背景检测要快得多,脾气也不那么暴躁。但正如你所注意到的,你不能使用iBeacon连接到使用核心蓝牙的外围设备。所以你必须在你的BLE设备上做广告。这是我一直使用的常用方法。使用iBeacon加速唤醒您的应用程序,并检测CoreBluetooth服务广告以建立连接。