通过iBeacon监控和测距与CoreBluetooth scanForPeripheralsWithServices检测信标

Ore*_*ren 19 ios core-bluetooth bluetooth-lowenergy ibeacon

关于iOS对想要扫描BLE信标\外设的应用程序所施加的限制存在很多困惑.在阅读了几篇博客和Stack Overflow答案之后,我想看看我是否正确理解了所有问题.如果有什么我误解或错过了,请纠正我.我只提到iOS 7及更高版本,专注于检测而不是连接(你能使用iBeacon Monitoring&Ranging API连接到CLBeacon吗?).

信标的选项很明确 - 使用通用BLE外设或使用以iBeacon格式通告的BLE外设(此外,非标准外设可以在adv-packet中以iBeacon格式进行通告,并在扫描响应包).

一般限制

  • iBeacon Ranging会让你知道你周围的信标.您必须指定信标预先通告的ProximityUUID(无"一般"扫描).didRangeBeacons将使用最近找到的CLBeacon对象数组每秒调用一次.距离信标的距离及其准确度由iOS使用一些机密算法计算,只有Apple的开发人员才知道(该算法基于rssi值和信标所宣传的rssi-at-1米校准字节).每次进入或退出某个区域时,您也可以使用iBeacon Monitoring来呼叫代理 - 您必须再次指定您要查找的ProximityUUID(您还可以指定主要和次要)."退出某个地区"的定义是一段时间没有收到任何广告,因此不能立即进行.每台设备可以同时监控的区域数量 限制为20 - 这意味着如果其他应用同时监控\范围,您的应用可能无法监控\范围(对吗?).
  • CoreBluetooth - 您还可以检测信标广告中的其他广告结构.如果信标也以iBeacon格式进行广告,您无法看到iBeacon字段(ProximityUUID,主要,次要......),尽管它们是在标准的"制造商特定"广告结构下发送的,您可以在其他情况下看到.

在前台运行 - 限制较少的用例:

  • iBeacon测距和监控 - 没有进一步的限制.
  • CoreBluetooth - Passing nil in the serviceUUIDs of scanForPeripheralsWithServices will scan for all peripherals. Passing CBCentralManagerScanOptionAllowDuplicatesKey as YES in the options will make the didDiscoverPeripheral to be called multiple times for the same peripheral\beacon (I assume that using a timer you detect the advertisement was not received for some time and assume that the user exited the "region").

Running in the Background - The more restricted use-case:

  • iBeacon Ranging will not work directly. iBeacon Monitoring will call didEnterRegion and give the app runtime of 6 seconds - in which you can start Ranging (for example, to detect major & minor). The detection may not be immediate since iOS turns scanning on and off to preserve the battery power. If you enter a region of multiple beacons with the same ProximityUUID, and you monitor this UUID without a specific major and\or minor, didEnterRegion will be called when you start receiving the signal from the first beacon - however, if you did not exit the region of the first beacon and you also entered the region of a second beacon the app will not be woken up again (didEnterRegion will not be called again) so you cannot start ranging to detect the second beacon's major & minor. The app cannot simply pop up to the foreground, but can create local notifications and other background operations.
  • CoreBluetooth - According to Core Bluetooth Background Processing scanForPeripheralsWithServices can run in the background using, but you must specify at least one serviceUUID. didDiscoverPeripheral will be given a runtime of 10 seconds. Using CBCentralManagerScanOptionAllowDuplicatesKey will not work - didDiscoverPeripheral will be called once for every peripheral. Therefore, you cannot detect "exit" from the region and "re-entry". I suppose you can use a non-standard BLE peripheral that changes its MAC address to overcome this issue. The app cannot simply pop up to the foreground, but can create local notifications and other background operations. The detection may not be immediate since iOS turns scanning on and off to preserve the battery power.

Running after the app is killed

  • iBeacon Monitoring - Works! Even if the user killed the app or the device was restarted.
  • CoreBluetooth - 如果应用程序被iOS杀死(由于不活动或内存限制),该应用程序将被唤醒.但是,如果用户明确杀死了应用程序,它将不会被唤醒(这使得第一个案例难以测试).我不知道设备重启后会发生什么......

有没有人有这些限制的经验?可以scanForPeripheralsWithServices被用作一些用例来iBeacon显示监控一个更好的选择?

谢谢!

dav*_*ung 5

你的描述基本上是正确的。只需要澄清两点:

  • 20 个区域限制不是针对每个设备的,而是特定于应用程序的。无论其他应用程序在移动设备上做什么,iOS 仍然允许您的应用程序监控最多 20 个区域。也就是说,可能存在特定于设备的硬件限制,即在硬件协助下可以在后台监控多少个区域。这些限制没有记录。如果超过这些未记录的限制,可能需要更长的时间才能在后台检测到信标。(尽管如此,操作系统无法保证检测何时到来。)

  • 您无法使用监控和测距 API 连接到CLBeacon。这些 API 仅适用于无连接的 BLE 广告数据包。

是的,可以用作scanForPeripheralsWithServices替代方案。这就是万向节信标为了实施专有系统所做的事情。然而,在背景检测时间和可靠性方面存在真正的缺点。