我正在我的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")
}
}
我希望在两个设备上都进行写操作,如果两者都已连接,则要在另一个上写。
谢谢。 爱神。
答案 0 :(得分:0)
对于那些仍然坚持这一点的人:- 当您尝试订阅它不属于的外围设备上的特性时,就会发生这种情况。我看到了同样的问题,并通过意识到我有附加所有特征的特征列表来修复它,所以当你要订阅你的外围设备不属于的特征时,通常会出现这样的问题发生。此外,我正在存储外围设备,然后在最近连接的设备上为这些特性订阅 notify 功能。这是该问题的另一个原因。
最重要的是,请确保:-您的特征正在订阅正确的外围设备