使用Swift获取设备名称的Corebluetooth

3

我正在使用CoreBluetooth框架在我的iOS应用程序中扫描并连接到其他蓝牙设备。我能够成功地使用以下代码扫描设备:

var centralManager: CBCentralManager?
var peripherals = [CBPeripheral]()
centralManager = CBCentralManager(delegate: self, queue: DispatchQueue.main)

在CBCentralManagerDelegate中,我实现了以下代码:
extension ViewController: CBCentralManagerDelegate {
    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        if (central.state == .poweredOn){
            self.centralManager?.scanForPeripherals(withServices: nil, options: nil)
        }
    }

    func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {

        if !peripherals.contains(peripheral) {
            let localName = advertisementData[CBAdvertisementDataLocalNameKey]
            print("\(String(describing: localName))" )
            peripherals.append(peripheral)
            tableView.reloadData()            
        }
    }
}

从上面的代码可以看出,localName始终为nil。我漏掉了什么代码吗?

添加更多信息:
在我的Mac上扫描蓝牙设备时,我能够看到设备的名称。但当我在我的iPhone上扫描蓝牙设备时,没有列出任何设备。

我进行了交叉检查,并确保我启用了其他4个设备的蓝牙(iPad、2个Android手机和1个Android电视)。


在执行peripherals.append(peripheral)之前,请检查advertisementData[CBAdvertisementDataLocalNameKey]是否存在。问题在于广告数据包可以分段完成(因为大小受限),完整的广告稍后才会到来。 - Larme
谢谢@Larme,我会添加这个检查。我探索了一些来自iTunes的其他应用程序,它们都显示标识符而不是名称。在iOS中无法获取设备名称吗? - Satyam
4个回答

2

使用Core Bluetooth库的Swift:

func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber){

    let peripheralLocalName_advertisement = ((advertisementData as NSDictionary).value(forKey: "kCBAdvDataLocalName")) as? String

    if (((advertisementData as NSDictionary).value(forKey: "kCBAdvDataLocalName")) != nil)

         print(peripheralLocalName_advertisement)//peripheral name from advertismentData

         print(peripheral.name)//peripheral name from peripheralData

         peripherals.append(peripheral) 

         arrayPeripheral.append(advertisementData)
    }
}

1

我只更改了您代码中名称的来源 - 不再使用:

let localName = advertisementData[CBAdvertisementDataLocalNameKey]

而是使用:

let localName = peripheral.name

现在我可以看到周围蓝牙设备的名称。


我也尝试过了。对我来说,peripheral.name也是nil。 - Satyam
2
仅仅是说...这是一条不同的信息。"peripheral.name"来自于物理设备本身(例如树莓派或其他设备的名称),而Local Name则是BLE广告的一个参数。 - RowanPD

0

didDiscoverPeripheral 回调函数不幸的是可能会返回 nilCBPeripheral 名称,以及在你开始扫描后应用程序获取到的第一个回调中 advertisementData 的本地名称。

如果你知道你正在使用的外设将在蓝牙广告数据包中包含本地名称,那么你可以选择忽略第一个包含 nil 名称的回调。

// In didDiscoverPeripheral
guard let peripheralName = peripheral.name else { return }
print("Did discover peripheral: \(peripheralName), RSSI: \(RSSI)")

0

我在你的代码中只更改了名称来源 - 改为:

let localName = advertisementData[CBAdvertisementDataLocalNameKey]

我使用:

let localName = peripheral.name

现在我可以看到周围的BLE设备名称。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接