问题
I am attempting to detect battery levels for connected BT devices on macOS. While I can get CBCentralManager to detect SOME nearby devices, all of the devices it detects are name=Null, even though there are numerous devices that should be detected and should have names (e.g., AirPods, magic trackpad, magic keyboard, etc).
My BT Manager class is:
import Cocoa
import CoreBluetooth
class BluetoothManager: NSObject, CBCentralManagerDelegate, CBPeripheralDelegate {
var centralManager = CBCentralManager()
var peripheralManager = CBPeripheralManager()
var discoveredPeripherals:[CBPeripheral]?
var selectedPeripheral:CBPeripheral?
let queue = DispatchQueue.main
let batteryLevelService = [CBUUID(string: "0x2A19")]
override init() {
self.centralManager = CBCentralManager(delegate: nil, queue: queue)
super.init()
centralManager.delegate = self
}
func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch central.state {
case .poweredOff:
print("BLE is powered off")
case .poweredOn:
print("BLE is powered on")
centralManager.scanForPeripherals(withServices: nil)
case .resetting:
print("BLE is resetting")
case .unauthorized:
print("BLE is not authorized")
case .unknown:
print("BLE state is unknown")
case .unsupported:
print("BLE is unsupported")
default:
print("Unable to determine BLE state")
}
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
print(peripheral)
}
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
// Code Here
}
}
I assign that class to an object in my main ViewController class.
I would normally have expected the console to show nearby discoverable devices as well as already-connected devices. However, all I get is:
<CBPeripheral: 0x600003508b00, identifier = C9A74282-A40C-46C1-9C2F-9646D2BCE8B5, name = (null), state = disconnected>
<CBPeripheral: 0x600003500840, identifier = 1EF2CD7F-8FAA-4510-A7DB-B4E060B2378B, name = (null), state = disconnected>
<CBPeripheral: 0x600003500a50, identifier = 1EF2CD7F-8FAA-4510-A7DB-B4E060B2378B, name = (null), state = disconnected>
<CBPeripheral: 0x600003508b00, identifier = BA372C81-993F-436D-994E-B31BDAB47BC7, name = (null), state = disconnected>
回答1:
Not all devices advertise their name. There is very little space in an advertising packet (~30 bytes), and the name may not fit if there are other more-important things to advertise. A single custom service can use up 16 bytes. You may not be able to determine the name without connecting. Even then, the device may not have a BLE name.
I would normally have expected the console to show nearby discoverable devices as well as already-connected devices.
I'm not sure why you expect that. scanForPeripherals
returns information about devices that are advertising. It is very common for a device to stop advertising when it's connected to (it's common for devices to only support a single connection). If you want to see connected devices, call retrieveConnectedPeripherals
.
来源:https://stackoverflow.com/questions/57834868/why-do-all-devices-discovered-by-cbcentralmanager-have-name-null