无法发现任何服务,但可以连接到设备

Can't discover any services, but can connect to device

我可以连接到 BLE 设备,但是 .discoverServices() 不工作。我的日志显示一个无用的一般错误:[CoreBluetooth] XPC connection invalid

连接到它确实有效:

    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)
    }

不确定我做错了什么,帮忙?


完整代码如下:

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
}

我发现我的代码中有两个错误。

  1. centralManagerDidUpdateState()central.state == .poweredOn 调用时,我正在调用 startScanning()。这导致扫描在调用 myCentral.connect(connectedPeripheral!, options: nil)
  2. 后立即再次开始
  3. myCentral.connect(connectedPeripheral!, options: nil) 之后调用 myCentral.stopScan() 导致断开连接

我不明白为什么会出现这些情况,但修复它们后我现在可以连接并获得服务和特征了!