通过 iBeacon Monitoring & Ranging 与 CoreBluetooth scanForPeripheralsWithServices 检测信标
Detecting beacons via iBeacon Monitoring & Ranging vs CoreBluetooth scanForPeripheralsWithServices
关于 iOS 对想要扫描 BLE beacons\peripherals 的应用程序施加的限制存在很多混淆。
在阅读了几篇博客和 Stack Overflow 的回答后,我想看看我是否正确理解了所有问题。如果有任何我误解或遗漏的地方,请纠正我。我只参考 iOS 7 及以上,并且专注于检测而不是连接(您可以使用 iBeacon Monitoring & Ranging API 连接到 CLBeacon 吗?)。
信标的选项很明确——使用通用 BLE 外围设备或使用在 iBeacon format 中发布广告的 BLE 外围设备(此外,非标准外围设备可以在 adv 中以 iBeacon 格式发布广告-数据包和扫描响应数据包中的不同格式)。
一般限制
- iBeacon Ranging 会让您知道您周围有哪些信标。您必须事先指定信标通告的 ProximityUUID(无 "general" 扫描)。
didRangeBeacons
将使用最近发现的 CLBeacon 对象数组每秒调用一次。与信标的距离及其精度由 iOS 使用一些只有 Apple 开发人员真正知道的机密算法计算得出(该算法基于信标的 rssi 值和 rssi-at-1-meter 校准字节做广告)。您还可以在每次进入或退出区域时使用 iBeacon Monitoring 调用委托 - 同样,您必须指定要查找的 ProximityUUID(您还可以指定主要和次要)。 "Exiting a region"定义为一段时间没有收到任何广告,因此不能立即。每个设备 可以同时 ranged\monitored 的区域数量 限制为 20 - 这意味着如果其他应用同时 monitoring\ranging,您的应用可能不能 monitor\range(对吧?)。
- CoreBluetooth - 您还可以检测信标广告中的其他广告结构。如果信标也以 iBeacon 格式进行广告,您将看不到 iBeacon 字段(ProximityUUID、主要、次要...),尽管它们是在您可以在其他格式中看到的标准 "Manufacturer Specific" 广告结构下发送的个案。
运行 在前台 - 限制较少的用例:
- iBeacon 测距和监控 - 无进一步限制。
- CoreBluetooth - 在
scanForPeripheralsWithServices
的 serviceUUIDs
中传递 nil
将扫描所有外围设备。在选项中将 CBCentralManagerScanOptionAllowDuplicatesKey
作为 YES
传递将使 didDiscoverPeripheral
被多次调用相同的 peripheral\beacon (我假设使用计时器检测到未收到广告一段时间并假设用户退出 "region")。
运行 在后台 - 更受限制的用例:
- iBeacon 测距不会直接工作。 iBeacon Monitoring 将调用
didEnterRegion
并给应用程序 运行 6 秒的时间 - 您可以在其中开始测距(例如,检测主要和次要)。检测可能不会立即进行,因为 iOS 会打开和关闭扫描以节省电池电量。如果您进入具有相同 ProximityUUID 的多个信标的区域,并且您在没有特定主要 and\or 次要的情况下监视此 UUID,则当您开始从第一个信标接收信号时将调用 didEnterRegion
- 但是,如果您没有退出第一个信标的区域并且您还进入了第二个信标的区域,则该应用程序将不会再次被唤醒(didEnterRegion
不会再次被调用)因此您无法开始测距以检测第二个信标的主要和次要。该应用不能简单地弹出到前台,但可以创建本地通知和其他后台操作。
- CoreBluetooth - 根据Core Bluetooth Background Processing
scanForPeripheralsWithServices
可以运行在后台使用,但是你必须至少指定一个serviceUUID。 didDiscoverPeripheral
的 运行 时间为 10 秒。使用 CBCentralManagerScanOptionAllowDuplicatesKey
将不起作用 - didDiscoverPeripheral
将为每个外设调用一次。因此,您无法从该区域检测到 "exit" 和 "re-entry"。我想你可以使用一个非标准的 BLE 外设来改变它的 MAC 地址来解决这个问题。该应用不能简单地弹出到前台,但可以创建本地通知和其他后台操作。检测可能不会立即进行,因为 iOS 会打开和关闭扫描以节省电池电量。
运行 应用被杀死后
- iBeacon 监控 - 有效!即使用户终止了应用程序或设备重新启动。
- CoreBluetooth - 如果应用被 iOS 杀死(由于不活动或内存限制),应用将被唤醒。但是,如果用户明确终止了该应用程序,它将不会被唤醒(这使得第一种情况难以测试)。我不知道设备重启后会发生什么...
有没有人对这些限制有更多经验? scanForPeripheralsWithServices
在某些用例中可以用作 iBeacon 监控的更好替代方案吗?
谢谢!
您的描述基本正确。仅需澄清两点:
20 个区域限制是每个设备 而不是 ,它是特定于应用程序的。无论其他应用程序在移动设备上做什么,您的应用程序仍被允许监控多达 20 个区域iOS。也就是说,可能存在特定于设备的硬件限制,即在硬件协助下可以在后台监控多少区域。这些限制没有记录。如果您超过这些未记录的限制,则可能需要更长的时间才能在后台检测到信标。 (尽管如此,无论如何,无法 OS 保证检测何时到来。)
您无法使用监控和测距 API 连接到 CLBeacon
。这些 API 仅适用于无连接的 BLE 广告数据包。
是的,可以使用 scanForPeripheralsWithServices
作为替代。这就是 Gimbal 信标为实施专有系统所做的事情。然而,就背景检测时间和可靠性而言,存在真正的缺点。
关于 iOS 对想要扫描 BLE beacons\peripherals 的应用程序施加的限制存在很多混淆。 在阅读了几篇博客和 Stack Overflow 的回答后,我想看看我是否正确理解了所有问题。如果有任何我误解或遗漏的地方,请纠正我。我只参考 iOS 7 及以上,并且专注于检测而不是连接(您可以使用 iBeacon Monitoring & Ranging API 连接到 CLBeacon 吗?)。
信标的选项很明确——使用通用 BLE 外围设备或使用在 iBeacon format 中发布广告的 BLE 外围设备(此外,非标准外围设备可以在 adv 中以 iBeacon 格式发布广告-数据包和扫描响应数据包中的不同格式)。
一般限制
- iBeacon Ranging 会让您知道您周围有哪些信标。您必须事先指定信标通告的 ProximityUUID(无 "general" 扫描)。
didRangeBeacons
将使用最近发现的 CLBeacon 对象数组每秒调用一次。与信标的距离及其精度由 iOS 使用一些只有 Apple 开发人员真正知道的机密算法计算得出(该算法基于信标的 rssi 值和 rssi-at-1-meter 校准字节做广告)。您还可以在每次进入或退出区域时使用 iBeacon Monitoring 调用委托 - 同样,您必须指定要查找的 ProximityUUID(您还可以指定主要和次要)。 "Exiting a region"定义为一段时间没有收到任何广告,因此不能立即。每个设备 可以同时 ranged\monitored 的区域数量 限制为 20 - 这意味着如果其他应用同时 monitoring\ranging,您的应用可能不能 monitor\range(对吧?)。 - CoreBluetooth - 您还可以检测信标广告中的其他广告结构。如果信标也以 iBeacon 格式进行广告,您将看不到 iBeacon 字段(ProximityUUID、主要、次要...),尽管它们是在您可以在其他格式中看到的标准 "Manufacturer Specific" 广告结构下发送的个案。
运行 在前台 - 限制较少的用例:
- iBeacon 测距和监控 - 无进一步限制。
- CoreBluetooth - 在
scanForPeripheralsWithServices
的serviceUUIDs
中传递nil
将扫描所有外围设备。在选项中将CBCentralManagerScanOptionAllowDuplicatesKey
作为YES
传递将使didDiscoverPeripheral
被多次调用相同的 peripheral\beacon (我假设使用计时器检测到未收到广告一段时间并假设用户退出 "region")。
运行 在后台 - 更受限制的用例:
- iBeacon 测距不会直接工作。 iBeacon Monitoring 将调用
didEnterRegion
并给应用程序 运行 6 秒的时间 - 您可以在其中开始测距(例如,检测主要和次要)。检测可能不会立即进行,因为 iOS 会打开和关闭扫描以节省电池电量。如果您进入具有相同 ProximityUUID 的多个信标的区域,并且您在没有特定主要 and\or 次要的情况下监视此 UUID,则当您开始从第一个信标接收信号时将调用didEnterRegion
- 但是,如果您没有退出第一个信标的区域并且您还进入了第二个信标的区域,则该应用程序将不会再次被唤醒(didEnterRegion
不会再次被调用)因此您无法开始测距以检测第二个信标的主要和次要。该应用不能简单地弹出到前台,但可以创建本地通知和其他后台操作。 - CoreBluetooth - 根据Core Bluetooth Background Processing
scanForPeripheralsWithServices
可以运行在后台使用,但是你必须至少指定一个serviceUUID。didDiscoverPeripheral
的 运行 时间为 10 秒。使用CBCentralManagerScanOptionAllowDuplicatesKey
将不起作用 -didDiscoverPeripheral
将为每个外设调用一次。因此,您无法从该区域检测到 "exit" 和 "re-entry"。我想你可以使用一个非标准的 BLE 外设来改变它的 MAC 地址来解决这个问题。该应用不能简单地弹出到前台,但可以创建本地通知和其他后台操作。检测可能不会立即进行,因为 iOS 会打开和关闭扫描以节省电池电量。
运行 应用被杀死后
- iBeacon 监控 - 有效!即使用户终止了应用程序或设备重新启动。
- CoreBluetooth - 如果应用被 iOS 杀死(由于不活动或内存限制),应用将被唤醒。但是,如果用户明确终止了该应用程序,它将不会被唤醒(这使得第一种情况难以测试)。我不知道设备重启后会发生什么...
有没有人对这些限制有更多经验? scanForPeripheralsWithServices
在某些用例中可以用作 iBeacon 监控的更好替代方案吗?
谢谢!
您的描述基本正确。仅需澄清两点:
20 个区域限制是每个设备 而不是 ,它是特定于应用程序的。无论其他应用程序在移动设备上做什么,您的应用程序仍被允许监控多达 20 个区域iOS。也就是说,可能存在特定于设备的硬件限制,即在硬件协助下可以在后台监控多少区域。这些限制没有记录。如果您超过这些未记录的限制,则可能需要更长的时间才能在后台检测到信标。 (尽管如此,无论如何,无法 OS 保证检测何时到来。)
您无法使用监控和测距 API 连接到
CLBeacon
。这些 API 仅适用于无连接的 BLE 广告数据包。
是的,可以使用 scanForPeripheralsWithServices
作为替代。这就是 Gimbal 信标为实施专有系统所做的事情。然而,就背景检测时间和可靠性而言,存在真正的缺点。