【问题标题】:BLE Peripheral delegate not called未调用 BLE 外设委托
【发布时间】:2017-11-17 01:18:06
【问题描述】:

我最近从 Swift 3 升级到了 Swift 4,从 iOS 10.3.3 升级到了 iOS 11.1。

我正在开发一个使用 BLE 进行双向通信的应用程序。工作流程如下:

  1. 外围设备 - 广告身份
  2. CENTRAL - 接收身份(处理它...)
  3. CENTRAL - 响应外围设备
  4. 外围设备 - 从中​​央接收响应
  5. 完成

我的代码在更新之前运行良好,但现在不行了。在第 4 步结束时,我执行以下行:

peripheral.writeValue(encryptedData!, for: characteristic, type: .withResponse)

这应该调用以下委托方法,但它没有:

public func peripheral(_ peripheral: CBPeripheral, didWriteValueFor descriptor: CBDescriptor, error: Error?) {
        print("Did Write")
        print("Error=\(error?.localizedDescription)")
    }

它还应该(并且正在调用)外围设备上的以下委托方法,但它没有:

public func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveWrite requests: [CBATTRequest]) {
        print("did receive write request")
}

服务和特性设置如下:

let prefs = Preferences()
            let strServiceUUID = prefs.GetString(key: Preferences.PREF_IDENTITY_SERVICE_UUID, defaultVal: "")!
            let strCharacteristicUUID = prefs.GetString(key: Preferences.PREF_IDENTITY_CHARACTERISTIC_UUID, defaultVal: "")!
            print("ServiceUUID=\(strServiceUUID)")
            print("CharacteristicUUID=\(strCharacteristicUUID)")
            mServiceUUID = CBUUID(string: strServiceUUID)
            mCharacterUUID = CBUUID(string: strCharacteristicUUID)
            mCBBluetoothServices = CBMutableService(type: mServiceUUID, primary: true)
            
            //lets configure the data we want to advertise for
            var characteristics : [CBCharacteristic] = []
            
            //let strData : String = "933911"
            //let data = strData.data(using: .utf8)
            let cbProperties: CBCharacteristicProperties = [.read, .write, .notify]
            let cbPermissions: CBAttributePermissions = [.readable, .writeable]
            mIdentityObjectCharacteristic = CBMutableCharacteristic(type: mCharacterUUID,
                                                                    properties: cbProperties,
                                                                    value: nil,
                                                                    permissions: cbPermissions)
            
            
            characteristics.append(mIdentityObjectCharacteristic)
            mCBBluetoothServices.characteristics = characteristics
            mCBPeripheralManager.add(mCBBluetoothServices)

【问题讨论】:

    标签: ios swift core-bluetooth


    【解决方案1】:

    我不确定为什么升级 OS 和 Swift 版本会破坏您的代码,但是在我看来您可能使用了错误的委托方法?

    试试这个

    func peripheral(CBPeripheral, didWriteValueFor: CBCharacteristic, error: Error?)
    

    而不是这个

    func peripheral(CBPeripheral, didWriteValueFor: CBDescriptor, error: Error?)
    

    【讨论】:

    • 我把它改成了正确的委托方法,但是当我调用 peripheral.writeValue(encryptedData!, for: characteristic, type: .withResponse) 时它仍然没有陷入陷阱。
    • 这很不幸。您是否确保您确实已连接、拥有所有权限、启用了 BLE 等?我自己升级到 iOS 后遇到了一些 BLE 连接问题,特别是对于 iPhone 5s 等旧手机。如果您发布更多代码,我可以进行比较,看看我们是否看到了相同的问题。
    【解决方案2】:

    斯威夫特 4

    对于任何类型的更新特性(例如读/写特性),将调用 didUpdateValueFor 委托。

    所以,首先检查以下委托方法。

    func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
        
        print("didUpdateValueForChar", characteristic)
        
        if let error1 = error{
            
            alertMSG(titleString: "Error", subTitleString: "Found error while read characteristic data, Plase try again", buttonTitle: "OK")
            
            print(error1)
        }
        else{
            
            print("Update Characteristic: ", characteristic)
        }
    }
    
    func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
        
        print("Write Characteristic :", characteristic)
    }
    

    【讨论】:

      【解决方案3】:

      斯威夫特 5
      iOS 13

      需要检查的一些事项:

      1. 确保将外设的delegate 设置为符合CBPeripheralDelegate 协议的任何控制器(这也应该是需要实现peripheral(_:didWriteValueFor:error:) 方法的同一控制器)。
      2. 确保您没有指定 .withoutResponse 写入类型。
      3. 正如this other answer 所提到的,有两个非常相似的委托方法具有签名peripheral(_:didWriteValueFor:error:)。确保你正在实施正确的。

      容易混淆2组write和delegate方法。

      由于您正在使用:

      peripheral.writeValue(encryptedData!, for: characteristic, type: .withResponse) 
      

      write 和 delegate 对的代码应该是这样的:

      class BluetoothController: CBCentralManagerDelegate, CBPeripheralDelegate {
      
          ...
         
          func writeSomething(to characteristic: CBCharacteristic, of peripheral: CBPeripheral) {
              let something = "1234"
              
              NSLog("Writing \(something) to \(characteristic.uuid.uuidString)")
              
              peripheral.delegate = self  // <===== You may have forgotten this?
              peripheral.writeValue(something.data(using: .utf8)!,
                                    for: characteristic,
                                    type: .withResponse)
          }
      
          ...
      
          func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
              if error != nil {
                  NSLog("Write error: \(String(describing: error))")
              } else {
                  NSLog("Wrote value to \(characteristic.uuid.uuidString)")
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2012-03-18
        • 1970-01-01
        • 2019-10-28
        • 1970-01-01
        • 2016-04-06
        • 2014-03-18
        • 2019-08-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多