如何使用 CoreBluetooth 只扫描信标
How to scan only for beacons with CoreBluetooth
我用这个功能扫描身边的BLE,但是接收到的信号太多了。我只想使用来自信标的信号。
func centralManagerDidUpdateState(_ central: CBCentralManager) {
centralManager.scanForPeripherals(withServices: nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey : NSNumber(value: true)])
}
I had used LightBlue 发现我的 beacon 有 5 个服务:180A、FFA0、FFB0、FFF0 和 180F。
然后我尝试了这个代码,但是没有找到这个服务的外围设备。
let serviceUUIDs = [CBUUID(string: "FFA0")]
func centralManagerDidUpdateState(_ central: CBCentralManager) {
centralManager.scanForPeripherals(withServices: serviceUUIDs, options: [CBCentralManagerScanOptionAllowDuplicatesKey : NSNumber(value: true)])
}
并且从未调用过 didDiscover 方法
func centralManager(_ central: CBCentralManager,
didDiscover peripheral: CBPeripheral,
advertisementData: [String : Any],
rssi: NSNumber)
{
if peripheral.name == "MY_BEACON_NAME" {
print("peripheral: \(peripheral)")
print("rssi = \(rssi)")
}
}
我做错了什么?
P. S. 我不能为这个项目使用 CoreLocation,只能使用 CoreBluetooth。
根据您的硬件信标广播的信标格式,可能无法使用 CoreBluetooth 进行检测。 CoreBluetooth 可以检测Eddystone 格式和AltBeacon 格式,但不能检测iBeacon 格式。
需要理解的几点:
信标格式不一定包含 GATT 服务 UUID,这是您在使用代码行 centralManager.scanForPeripherals(withServices: serviceUUIDs ...
时要过滤的内容。虽然 Eddystone 广告确实包含服务 UUID,但 iBeacon 和 AltBeacon 不包含,因为它们是另一种 BLE 广告,称为制造商广告。只有 GATT 广告有服务 UUID。
Eddystone 格式使用 FEAA 服务 UUID,您可以使用您描述的技术来过滤此信标类型。
你只能检测没有 serviceUUID 过滤器的 AltBeacon 广告,因为它没有。
你 永远不会 检测到带有 CoreBluetooth 的 iBeacon,因为 Apple 有特殊的代码过滤器可以阻止他的 API 接收这些广告。您别无选择,只能在 iOS.
上使用 CoreLocation 进行 iBeacon 检测
许多信标硬件制造商还包括一些具有自己的服务 UUIDS 的补充 GATT 服务。这些服务执行配置或附加操作等功能。但是这些与信标功能无关,并且无法知道何时(如果有的话)这些服务 UUID 被公布,以及它们的含义。这些 UUID 从一个信标制造商到另一个信标制造商绝对不同。 LightBlue 检测到的服务 UUID 可能是补充服务,因此它们根本无助于解决此问题。
底线:没有简单的方法可以使用 CoreBluetooth 仅过滤您想要的信标。你最好的选择是在 CoreBluetooth 之上编写你自己的过滤软件,并简单地忽略你不关心的数据包。
我用这个功能扫描身边的BLE,但是接收到的信号太多了。我只想使用来自信标的信号。
func centralManagerDidUpdateState(_ central: CBCentralManager) {
centralManager.scanForPeripherals(withServices: nil, options: [CBCentralManagerScanOptionAllowDuplicatesKey : NSNumber(value: true)])
}
I had used LightBlue 发现我的 beacon 有 5 个服务:180A、FFA0、FFB0、FFF0 和 180F。
然后我尝试了这个代码,但是没有找到这个服务的外围设备。
let serviceUUIDs = [CBUUID(string: "FFA0")]
func centralManagerDidUpdateState(_ central: CBCentralManager) {
centralManager.scanForPeripherals(withServices: serviceUUIDs, options: [CBCentralManagerScanOptionAllowDuplicatesKey : NSNumber(value: true)])
}
并且从未调用过 didDiscover 方法
func centralManager(_ central: CBCentralManager,
didDiscover peripheral: CBPeripheral,
advertisementData: [String : Any],
rssi: NSNumber)
{
if peripheral.name == "MY_BEACON_NAME" {
print("peripheral: \(peripheral)")
print("rssi = \(rssi)")
}
}
我做错了什么?
P. S. 我不能为这个项目使用 CoreLocation,只能使用 CoreBluetooth。
根据您的硬件信标广播的信标格式,可能无法使用 CoreBluetooth 进行检测。 CoreBluetooth 可以检测Eddystone 格式和AltBeacon 格式,但不能检测iBeacon 格式。
需要理解的几点:
信标格式不一定包含 GATT 服务 UUID,这是您在使用代码行
centralManager.scanForPeripherals(withServices: serviceUUIDs ...
时要过滤的内容。虽然 Eddystone 广告确实包含服务 UUID,但 iBeacon 和 AltBeacon 不包含,因为它们是另一种 BLE 广告,称为制造商广告。只有 GATT 广告有服务 UUID。Eddystone 格式使用 FEAA 服务 UUID,您可以使用您描述的技术来过滤此信标类型。
你只能检测没有 serviceUUID 过滤器的 AltBeacon 广告,因为它没有。
你 永远不会 检测到带有 CoreBluetooth 的 iBeacon,因为 Apple 有特殊的代码过滤器可以阻止他的 API 接收这些广告。您别无选择,只能在 iOS.
上使用 CoreLocation 进行 iBeacon 检测
许多信标硬件制造商还包括一些具有自己的服务 UUIDS 的补充 GATT 服务。这些服务执行配置或附加操作等功能。但是这些与信标功能无关,并且无法知道何时(如果有的话)这些服务 UUID 被公布,以及它们的含义。这些 UUID 从一个信标制造商到另一个信标制造商绝对不同。 LightBlue 检测到的服务 UUID 可能是补充服务,因此它们根本无助于解决此问题。
底线:没有简单的方法可以使用 CoreBluetooth 仅过滤您想要的信标。你最好的选择是在 CoreBluetooth 之上编写你自己的过滤软件,并简单地忽略你不关心的数据包。