Puedo conectarme a un dispositivo BLE, pero .discoverServices() no funciona. Mis registros muestran un error genérico inútil: [CoreBluetooth] XPC connection invalid
Conectarse a él funciona:
func connectToPeripheral(id: Int) -> Bool { guard id >= 0 && id <= peripherals.count else { return false } let arrayItem = peripherals[id] connectedPeripheral = arrayItem.peripheral connectedPeripheral!.delegate = self myCentral.connect(connectedPeripheral!, options: nil) print("connected to \(arrayItem.name)") myCentral.stopScan() return true } func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { print("Connected to \(String(describing: peripheral.name)) \(peripheral.description)!") print(peripheral.services as Any) peripheral.discoverServices(nil) }Pero esta función nunca se llama. ¿¿¿¿Por qué????
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { print("Services:") print(peripheral.services as Any) }No estoy seguro de lo que estoy haciendo mal, ¿ayuda?
Aquí está el código completo:
import Foundation import CoreBluetooth class BLEManager: NSObject, ObservableObject, CBCentralManagerDelegate, CBPeripheralDelegate { var myCentral: CBCentralManager! @Published var isSwitchedOn = false @Published var peripherals = [Peripheral]() @Published var connectedPeripheral: CBPeripheral? override init() { super.init() myCentral = CBCentralManager(delegate: self, queue: nil) myCentral.delegate = self } func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) { var peripheralName: String! if let name = advertisementData[CBAdvertisementDataLocalNameKey] as? String { peripheralName = name } else { peripheralName = "Unknown" } if peripherals.contains(where: { p in p.name == peripheralName }) { return } let newPeripheral = Peripheral(id: peripherals.count, name: peripheralName, rssi: RSSI.intValue, peripheral: peripheral) peripherals.append(newPeripheral) } func startScanning() { print("startScanning") peripherals.removeAll() myCentral.scanForPeripherals(withServices: nil, options: nil) } func stopScanning() { print("stopScanning") myCentral.stopScan() } func connectToPeripheral(id: Int) -> Bool { guard id >= 0 && id <= peripherals.count else { return false } let arrayItem = peripherals[id] connectedPeripheral = arrayItem.peripheral connectedPeripheral!.delegate = self myCentral.connect(connectedPeripheral!, options: nil) print("connected to \(arrayItem.name)") myCentral.stopScan() return true } func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) { print("Connected to \(String(describing: peripheral.name)) \(peripheral.description)!") print(peripheral.services as Any) peripheral.discoverServices(nil) } func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) { print("Services:") print(peripheral.services as Any) } func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) { print("got Characteristics...") } func centralManagerDidUpdateState(_ central: CBCentralManager) { print("centralManagerDidUpdateState: poweredOn=\(central.state == .poweredOn)") if central.state == .poweredOn { //if it wasn't previously on, start scanning if !isSwitchedOn { isSwitchedOn = true startScanning() } } else { isSwitchedOn = false } } } struct Peripheral: Identifiable { let id: Int let name: String let rssi: Int let peripheral: CBPeripheral }Descubrí dos errores en mi código.
startScanning() cuando se llamó a centralManagerDidUpdateState() con central.state == .poweredOn . Esto hace que el escaneo comience de nuevo justo después de llamar a myCentral.connect(connectedPeripheral!, options: nil)myCentral.stopScan() después de myCentral.connect(connectedPeripheral!, options: nil) estaba causando desconexionesNo entiendo por qué sucedía ninguno de los dos, pero arreglarlos me permitió conectarme y obtener servicios y características.