如何解决[CoreBluetooth]警告:对于具有多设备连接的外围设备而言,这不是有效的特征

时间:2019-05-12 19:10:32

标签: ios swift xcode bluetooth-lowenergy core-bluetooth

我正在我的iOS应用程序和几个BLE设备之间建立连接,这产生了我的自我。当只有一台设备连接时,我没有问题,但是当两台设备都连接时,我收到其中一个的错误消息:

  

[CoreBluetooth]警告:,通知= NO>不是外围设备的有效特征

这两个设备具有相同的服务名称和特征,但是它们具有不同的名称和标识符,我使用该名称来标识一个或另一个设备。

如果仅连接一个设备,则相同的代码可以正常工作。

我向您展示我的代码:

//BLE starts here
extension BTManager: CBCentralManagerDelegate {
    func centralManagerDidUpdateState(_ central: CBCentralManager) {
        switch central.state {
        case .unknown:
            print("central.state is .unknown")
            connectionStatus = -5
        case .resetting:
            print("central.state is .resetting")
            connectionStatus = -4
        case .unsupported:
            print("central.state is .unsupported")
            connectionStatus = -3
        case .unauthorized:
            print("central.state is .unauthorized")
            connectionStatus = -2
        case .poweredOff:
            print("central.state is .poweredOff")
            connectionStatus = -1
        case .poweredOn:
            print("central.state is .poweredOn and searching mode")
            connectionStatus = 0
            //Scan
            if (!centralManager.isScanning){
                centralManager.scanForPeripherals(withServices: [insoleServiceCBUUID])
            }
        }
    }

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

        if(isInsolePresentInUserDefaults()){

            let insolesDictionary = UserDefaults.standard.dictionary(forKey: "AriaSmartInsole") as! [String : String]

            if (peripheral.name! == insolesDictionary["leftInsole"]){

                leftDevicePeripheral = peripheral
                leftDevicePeripheral.delegate = self
                centralManager.connect(leftDevicePeripheral)

            }

            if (peripheral.name! == insolesDictionary["rightInsole"]){

                rightDevicePeripheral = peripheral
                rightDevicePeripheral.delegate = self
                centralManager.connect(rightDevicePeripheral)

            }

        //ELSE record couple devices
        }else{

                if (peripheral.name!.contains("Aria") && peripheral.name!.count > 8){

                    if (dispositiviTrovati.count > 1){

                        var dispositiviTrovatiArray: [CBPeripheral] = Array(Set(dispositiviTrovati))


                        for (index, element) in dispositiviTrovatiArray.enumerated(){

                            let nextElement = index + 1

                            if (nextElement < dispositiviTrovatiArray.count){

                                let nomePrimoDevice: String = dispositiviTrovatiArray[index].name!
                                let primoDevice: CBPeripheral = dispositiviTrovatiArray[index]
                                let nomeSuccessivoDevice: String = dispositiviTrovatiArray[nextElement].name!
                                let successivoDevice: CBPeripheral = dispositiviTrovatiArray[nextElement]
                                let latoPrimoDevice: Character = nomePrimoDevice[nomePrimoDevice.index(nomePrimoDevice.startIndex, offsetBy: 5)]
                                let latoSuccessivoDevice: Character = nomeSuccessivoDevice[nomeSuccessivoDevice.index(nomeSuccessivoDevice.startIndex, offsetBy: 5)]

                                //HERE I SEARCH FOR LEFT DEVICE AND RIGHT DEVICE OF A COUPLE 
                                if (nomePrimoDevice.suffix(8) == nomeSuccessivoDevice.suffix(8) && latoPrimoDevice != latoSuccessivoDevice){

                                    var deviceDictionary: [String:String] = [:]
                                    var deviceSinistro: CBPeripheral?
                                    var deviceDestro: CBPeripheral?

                                    if(latoPrimoDevice == "S"){
                                        deviceDictionary["leftInsole"] = nomePrimoDevice
                                        deviceSinistro = primoDevice
                                    }else if(latoPrimoDevice == "D"){
                                        deviceDictionary["rightInsole"] = nomePrimoDevice
                                        deviceDestro = primoDevice
                                    }

                                    if(latoSuccessivoDevice == "S"){
                                        deviceDictionary["leftInsole"] = nomeSuccessivoDevice
                                        deviceSinistro = successivoDevice
                                    }else if(latoSuccessivoDevice == "D"){
                                        deviceDictionary["rightInsole"] = nomeSuccessivoDevice
                                        deviceDestro = successivoDevice
                                    }

                                    //BINGO
                                    if(deviceDictionary.count == 2){

                                        print(deviceDictionary.description)

                                        UserDefaults.standard.set(deviceDictionary, forKey: "AriaSmartInsole")

                                        //ASK FOR CONNECTION COUPLE OF DEVICE
                                        for device in dispositiviTrovati{

                                            if (device.name! == UserDefaults.standard.dictionary(forKey: "AriaSmartInsole")!["leftInsole"] as! String){

                                                leftDevicePeripheral = deviceSinistro
                                                print(leftDevicePeripheral.name ?? "")
                                                leftDevicePeripheral.delegate = self
                                                centralManager.connect(leftDevicePeripheral)

                                            }else if(device.name! == UserDefaults.standard.dictionary(forKey: "AriaSmartInsole")!["rightInsole"] as! String){

                                                rightDevicePeripheral = deviceDestro
                                                print(rightDevicePeripheral.name ?? "")
                                                rightDevicePeripheral.delegate = self
                                                centralManager.connect(rightDevicePeripheral)

                                            }

                                        }

                                    }

                            }

                        }

                    }

                }

            }

        }

    }

//CONNECTED TO DEVICES
    func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {

        if (peripheral.name! == leftDevicePeripheral.name!){

            leftDevicePeripheral.isConnected = true
            leftDevicePeripheral.discoverServices([insoleServiceCBUUID])
            self.connectionStatus = 1

        }else if(peripheral.name! == rightDevicePeripheral.name!){

            rightDevicePeripheral.isConnected = true
            rightDevicePeripheral.discoverServices([insoleServiceCBUUID])
            self.connectionStatus = 1

        }

        if (leftDevicePeripheral.isConnected == true && rightDevicePeripheral.isConnected == true){

            self.connectionStatus = 2
            centralManager.stopScan()//Safe power

        }

    }

}
extension BTManager: CBPeripheralDelegate {

    //SERVICES FOUND
    func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {

        if (error != nil){

            print("didDiscoverServices ERROR: ", error.debugDescription);

            return;

        }

        var insoleServiceIsFound: Bool = false;

        for service in peripheral.services! {

            //FOUND MY SERVICE
            if (service.uuid == insoleServiceCBUUID){

                if (peripheral.name! == leftDevicePeripheral.name){

                    leftDevicePeripheral.insoleService = service
                    leftDevicePeripheral.discoverCharacteristics(nil, for: leftDevicePeripheral.insoleService)
                    insoleServiceIsFound = true;

                }else if (peripheral.name! == rightDevicePeripheral.name){

                    rightDevicePeripheral.insoleService = service
                    rightDevicePeripheral.discoverCharacteristics(nil, for: rightDevicePeripheral.insoleService)
                    insoleServiceIsFound = true;

                }

            }

        }

        if (!insoleServiceIsFound){

            print("didDiscoverServices: ARIA SERVICE NOT FOUND");

        }

    }

//CHARACTERISTIC OF MY SERVICE FOUND
    func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {

        if (error != nil){

            print("didDiscoverCharacteristicsFor ERROR: ", error.debugDescription)
            return
        }

        guard let characteristics = service.characteristics else {

            print("NO CHARACTERESTICS FOUND")
            return

        }

        if (peripheral.name! == leftDevicePeripheral.name){

            for characteristic in characteristics {

                switch characteristic.uuid {

                case userEnableCBUUID:

                    leftDevicePeripheral.temperatureEnableCharacteristic = characteristic

                    if characteristic.properties.contains(.read) {
                        print("\(characteristic.uuid): properties contains .read")
                        leftDevicePeripheral.readValue(for: leftDevicePeripheral.temperatureEnableCharacteristic)
                    }

                case batteryLevelCBUUID:

                    leftDevicePeripheral.batteryLevelCharacteristic = characteristic

                    if characteristic.properties.contains(.read) {
                        print("\(characteristic.uuid): properties contains .read")
                        leftDevicePeripheral.readValue(for: leftDevicePeripheral.batteryLevelCharacteristic)

                    }
                default:
                    print("Unhandled Characteristic UUID: \(characteristic.uuid)")
                }

            }

        }else if (peripheral.name! == rightDevicePeripheral.name){

            for characteristic in characteristics {

                switch characteristic.uuid {

                case userEnableCBUUID:

                    rightDevicePeripheral.temperatureEnableCharacteristic = characteristic

                    if characteristic.properties.contains(.read) {
                        print("\(characteristic.uuid): properties contains .read")
                        rightDevicePeripheral.readValue(for: rightDevicePeripheral.temperatureEnableCharacteristic)
                    }

                case batteryLevelCBUUID:

                    rightDevicePeripheral.batteryLevelCharacteristic = characteristic

                    if characteristic.properties.contains(.read) {
                        print("\(characteristic.uuid): properties contains .read")
                        rightDevicePeripheral.readValue(for: rightDevicePeripheral.batteryLevelCharacteristic)
                    }

                default:
                    print("Unhandled Characteristic UUID: \(characteristic.uuid)")
                }

            }

        }

    }

    //DATA RECEIVED
    func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {

        print("Nome: \(peripheral.name ?? "")")

        if (error != nil){

            print("didUpdateValueFor ERROR: ", error.debugDescription)
            return

        }


        if (peripheral.name! == leftDevicePeripheral.name){

            //Assegno valori prelevati alle caratteristiche
            switch characteristic.uuid {

            case userEnableCBUUID:

                print("userEnableValue: ", characteristic.value?[0] ?? "no value")
                //print("userTemp: ", characteristic.value?[0] ?? "no value")
                var data = characteristic.value
                var values = [UInt8](repeating:0, count:(data?.count)!)
                data?.copyBytes(to: &values, count:(data?.count)!)

                if(Int(values[0]) == 1){
                    leftDevicePeripheral.isThermalEnabled = true
                }else if(Int(values[0]) == 0){
                    leftDevicePeripheral.isThermalEnabled = false
                }
                print("LEFT userEnableValue for \(peripheral.description) in delegate:", leftDevicePeripheral.isThermalEnabled)
                print("\n")


            case batteryLevelCBUUID:

                //print("Battery level: ", characteristic.value?[0] ?? "no value")
                let data = characteristic.value
                var byte:UInt8 = 0
                data?.copyBytes(to: &byte, count: 1)
                leftDevicePeripheral.batteryLevel = Int(byte)
                print("BATTERY level: ", leftDevicePeripheral.batteryLevel)


            default:

                print("Unhandled Characteristic UUID: \(characteristic.uuid)")

            }

        }else if (peripheral.name! == rightDevicePeripheral.name){

            //Assegno valori prelevati alle caratteristiche
            switch characteristic.uuid {

            case userEnableCBUUID:

                print("RIght userEnableValue: ", characteristic.value?[0] ?? "no value")
                //print("userTemp: ", characteristic.value?[0] ?? "no value")
                var data = characteristic.value
                var values = [UInt8](repeating:0, count:(data?.count)!)
                data?.copyBytes(to: &values, count:(data?.count)!)

                if(Int(values[0]) == 1){
                    rightDevicePeripheral.isThermalEnabled = true
                }else if(Int(values[0]) == 0){
                    rightDevicePeripheral.isThermalEnabled = false
                }
                print("RIGHT userEnableValue for \(peripheral.description) in delegate:", leftDevicePeripheral.isThermalEnabled)
                print("\n")

            case batteryLevelCBUUID:

                //print("Battery level: ", characteristic.value?[0] ?? "no value")
                let data = characteristic.value
                var byte:UInt8 = 0
                data?.copyBytes(to: &byte, count: 1)
                let battLevel = Int(byte)
                print("BATTERY level: ", battLevel)


            default:

                print("Unhandled Characteristic UUID: \(characteristic.uuid)")

            }

        }

    }

//FUNC THAT I CALL
func enableThermal(forDevice: String){

        //Se c'è connessione
        if(self.checkConnessione() > 0){

            var val = UInt8(1)
            let data = NSData(bytes: &val, length: MemoryLayout<UInt8>.size)

            print("Val: \(val)")
            print("Data: \(data.description)")

                if((forDevice == "left" || forDevice == "both") && leftDevicePeripheral.temperatureEnableCharacteristic != nil){

                    leftDevicePeripheral.writeValue(data as Data, for: leftDevicePeripheral.temperatureEnableCharacteristic, type: CBCharacteristicWriteType.withResponse)


                }

                if((forDevice == "right" || forDevice == "both") && rightDevicePeripheral.temperatureEnableCharacteristic != nil){

                    rightDevicePeripheral.writeValue(data as Data, for: rightDevicePeripheral.temperatureEnableCharacteristic, type: CBCharacteristicWriteType.withResponse)



                }

        //Error msg + Ritenta connessione
        }else{

            print("NO CONNECTION")

        }

    }

我希望在两个设备上都进行写操作,如果两者都已连接,则要在另一个上写。

谢谢。 爱神。

1 个答案:

答案 0 :(得分:0)

对于那些仍然坚持这一点的人:- 当您尝试订阅它不属于的外围设备上的特性时,就会发生这种情况。我看到了同样的问题,并通过意识到我有附加所有特征的特征列表来修复它,所以当你要订阅你的外围设备不属于的特征时,通常会出现这样的问题发生。此外,我正在存储外围设备,然后在最近连接的设备上为这些特性订阅 notify 功能。这是该问题的另一个原因。

最重要的是,请确保:-您的特征正在订阅正确的外围设备