如果您使用 CoreBluetooth 而不是 CoreLocation 扫描信标,则检测到的每个广告数据包都会收到一个回调,而 CoreLocation 则每秒会收到一个回调。这两种方法都有优点和缺点,因此准确了解每种方法的工作原理以做出正确的选择非常重要。其优缺点很大程度上受信标的广告速率影响,标准的iBeacon广告速率为10 Hz。
使用 CoreLocation 测距
以下方法将每秒获取一次回调,但仅适用于与 iBeacon 布局匹配并与该布局中已注册用于测距的 ProximityUUID 的 BLE 广告CLBeaconRegion
目的。当满足这些条件时,每秒调用以下回调不管在该时间间隔内检测到多少个信标数据包:
locationManager(_ manager: CLLocationManager, didRangeBeacons beacons: [CLBeacon], in region: CLBeaconRegion)
.
Each CLBeacon
数组中的对象beacons
has a rssi
场地。该字段包含过去一秒间隔内检测到的所有信标数据包的平均 RSSI。
如果信标以 10 Hz 进行广播,则该 RSSI 读数将是过去一秒接收到的 8-10 个数据包的平均值(由于无线电噪声、冲突和干扰,通常仅接收到 80-90% 的数据包)。
如果信标以 1Hz 或更低的频率进行广告(典型的电池信标试图节省电量),则平均值中将只包含一个 RSSI 读数。 (无法知道回调返回的 rssi 值中有多少检测结果。)
因此,虽然您无法访问每次检测的 RSSI 值,并且无法控制平均间隔,但您确实可以从多次检测中受益,因为 RSSI 值是平均的,并且比有检测时的噪声更少。只读过一篇。因此,只要您愿意接受其硬编码的平均间隔,CoreLocation 即可为您提供与 CoreBluetooth 一样高的准确性。
The CLBeacon
对象还具有字段accuracy
and proximity
它们基于在较长时间间隔内过滤的 RSSI 派生值(实验显示约为 20 秒)。 API 无法控制此平均间隔,对于某些需要快速更新距离估计的应用程序来说,20 秒是一个非常长的延迟。
使用 CoreBluetooth 扫描
这通常是通过设置允许重复结果的标志来完成的:
centralManager.scanForPeripherals(withServices: [], options: [CBCentralManagerScanOptionAllowDuplicatesKey: true] )
当上述扫描开始时,会对检测到的每个蓝牙广告进行以下回调:
centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber)
此回调中的 rssi 编号是单包检测的原始值。如果您的信标以 10 Hz 进行广告,则在此方法中您每秒将收到 8-10 次回调(同样,并非 100% 收到数据包),并且您可以根据需要平均或过滤 rssi。这使您可以对 RSSI 的使用进行细粒度控制,并且可以在任意平均间隔内进行距离估计。
以上动机促使我开发开源iOS 信标工具 https://github.com/AltBeacon/ios-beacon-tools,允许检测培根CoreBluetooth
并根据在任意指定的平均间隔内收集的 RSSI 来计算距离估计。
然而,使用有几个缺点CoreBluetooth
:
iBeacon 数据包无法解码,因为操作系统会过滤掉与其布局匹配的任何数据包的数据负载。因此,您必须使用类似 AltBeacon 的布局,或者使用 Eddystone 框架。
像 AltBeacon 这样的制造商广告不会在后台投放,只会在前台投放。
像 Eddystone 这样的服务广告是在后台投放的,但速度非常非常慢。所以对于RSSI数据采集来说没有什么用处。