iOS对想要扫描BLE信标/外设的应用程序施加的限制令人困惑。阅读了几篇博客和Stack Overflow答案后,我想确认是否正确了解了所有问题。如果我有任何误解或遗漏,请纠正我。我仅参考iOS 7及以上版本,并且专注于检测而不是连接(您能否使用iBeacon Monitoring & Ranging API连接到CLBeacon?)。
信标的选项很明确-使用通用BLE外设或使用以iBeacon格式广告的BLE外设(非标准外设也可以在广告包中以iBeacon格式广告,并在扫描响应包中使用不同的格式)。
一般限制 iBeacon测距技术可以让你知道周围的信标。您必须预先指定信标广告的ProximityUUID(不能进行“通用”扫描)。每秒钟,
信标的选项很明确-使用通用BLE外设或使用以iBeacon格式广告的BLE外设(非标准外设也可以在广告包中以iBeacon格式广告,并在扫描响应包中使用不同的格式)。
一般限制 iBeacon测距技术可以让你知道周围的信标。您必须预先指定信标广告的ProximityUUID(不能进行“通用”扫描)。每秒钟,
didRangeBeacons
将呼叫最近发现的CLBeacon对象数组。iOS使用一些机密算法(该算法基于信标广告的rssi值和rssi-at-1-meter校准字节)来计算与信标的距离和精度。您还可以使用iBeacon监控,在进入或退出区域时调用委托-同样,您必须指定要查找的ProximityUUID(还可以指定major&minor)。"退出区域"是通过没有接收任何广告的某些时间来定义的,因此不可能是立即的。 每个设备可同时设置的区域数有限,最多为20个-这意味着如果其他应用程序同时进行监视\测距,您的应用程序可能无法监视\测距(对吧?)。
CoreBluetooth-您还可以检测信标广告中的其他广告结构。如果信标也以iBeacon格式广告,则无法看到iBeacon字段(ProximityUUID、major、minor...),尽管它们在其他情况下发送在标准的“制造商专用”广告结构下。
在前台运行 - 不受限制的用例:
- iBeacon范围和监控 - 没有进一步的限制。
- CoreBluetooth - 在
scanForPeripheralsWithServices
的serviceUUIDs
中传递nil
将扫描所有外设。在选项中传递CBCentralManagerScanOptionAllowDuplicatesKey
,并将YES
作为参数,将使didDiscoverPeripheral
对于同一外设\信标被多次调用(假定使用计时器检测到广告已经一段时间未收到,并且假定用户退出了“区域”)。
在后台运行 - 更受限制的用例:
iBeacon Ranging 无法直接使用。iBeacon Monitoring 将调用didEnterRegion
并给予应用程序 6 秒的运行时间,在此期间您可以启动 Ranging(例如,检测主要和次要信号)。由于 iOS 会开启和关闭扫描以节省电池电量,因此检测可能不是立即进行的。如果您进入一个具有相同 ProximityUUID 的多个 iBeacon 区域,并且在没有特定主要和 / 或次要信号的情况下监视此 UUID,则当您开始从第一个 iBeacon 接收到信号时,将调用 didEnterRegion
;但是,如果您没有退出第一个 iBeacon 区域并且还进入了第二个 iBeacon 区域,则应用程序不会再次唤醒(didEnterRegion
不会再次被调用),因此您无法启动 Ranging 以检测第二个 iBeacon 的主要和次要信号。应用程序不能简单地弹出到前台,但可以创建本地通知和其他后台操作。
CoreBluetooth - 根据 Core Bluetooth Background Processing,scanForPeripheralsWithServices
可以在后台运行,但必须指定至少一个 serviceUUID。 didDiscoverPeripheral
将获得 10 秒的运行时间。使用 CBCentralManagerScanOptionAllowDuplicatesKey
将无效 - didDiscoverPeripheral
会为每个外围设备调用一次。因此,您无法检测从区域“退出”和“重新进入”。我想您可以使用非标准的 BLE 外围设备来改变其 MAC 地址以克服此问题。应用程序不能简单地弹出到前台,但可以创建本地通知和其他后台操作。由于 iOS 会开启和关闭扫描以节省电池电量,因此检测可能不是立即进行的。
在应用程序被杀死后运行
- iBeacon监控 - 即使用户杀死了应用程序或设备重新启动,也可以使用!
- CoreBluetooth - 如果iOS由于不活动或内存限制而杀死了应用程序,则应用程序将被唤醒。但是,如果用户明确杀死了应用程序,则不会被唤醒(这使得第一种情况难以测试)。我不知道设备重新启动后会发生什么......
有没有人对这些限制有更多的经验?在某些用例中,scanForPeripheralsWithServices
能否作为iBeacon监控的更好替代品?
谢谢!