CoreBluetooth:在 writeValue() 之后不调用 didWriteValueFor()
CoreBluetooth: didWriteValueFor() is not called after writeValue()
根据 Apple Developer Documentation,函数 didWriteValueFor() 在 writeValue() 函数被调用之后被调用。 (参见 https://developer.apple.com/documentation/corebluetooth/cbperipheraldelegate/1518823-peripheral)
我有一个可写的特征,我查找了 https://developer.apple.com/documentation/corebluetooth/cbcharacteristicproperties/1519089-write
中提到的 属性
现在当我调用writeValue() 函数时,didWriteValueFor() 函数永远不会被调用,为什么?我认为它与调用 didUpdateValueFor() 函数的 readValue() 函数的结构相同,这对我来说工作正常。
这是我的代码:
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
for characteristic in service.characteristics!{
print(characteristic)
if(characteristic.uuid == TX_CHARACTERISTIC){
elsa.writeValue(dataWithHexString(hex: VALID_GET_VERSION_REQUEST), for: characteristic, type: CBCharacteristicWriteType.withResponse)//calls didWriteValueFor if Type = withResponse
}
if(characteristic.uuid == RX_CHARACTERISTIC){
elsa.setNotifyValue(true, for: characteristic)//calls didUpdateNotificationStateFor
}
}
}
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
guard let data = characteristic.value else { return }
print("\nValue: \(data.toHexEncodedString()) \nwas written to Characteristic:\n\(characteristic)")
if(error != nil){
print("\nError while writing on Characteristic:\n\(characteristic). Error Message:")
print(error as Any)
}
}
如@Paulw11 所述,该值仅在显式读取后写入。我通过在 didWrite() 函数中调用 readValue() 来解决这个问题。
更新的解决方案:
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
elsa.readValue(for: characteristic)
guard let data = characteristic.value else { return }
print("\nValue: \(data.toHexEncodedString()) \nwas written to Characteristic:\n\(characteristic)")
if(error != nil){
print("\nError while writing on Characteristic:\n\(characteristic). Error Message:")
print(error as Any)
}
}
当您调用 writeValue() 时,您可以指定是否需要来自远程设备的响应。在您的情况下,您指定了 CBCharacteristicWriteType.withResponse ,它告诉远程设备它需要发回响应并指示写入是否成功。当远程设备发送响应消息时,这将触发对 didWriteValueFor() 的调用。如果您的设备不发送响应,则不会调用 didWriteValueFor()。您可以在 apple documentation here 中阅读相关内容。您需要 运行 蓝牙嗅探器捕获来确认这一点,但我怀疑您的蓝牙设备没有正确响应 writeValue() 请求。
请注意,每个 BLE 特性都有一组属性来控制特性的行为方式。其中一些属性包括:rear、write、write without response、notify、inform。检查您正在使用的特征的属性,并确保它支持 'write' 属性。如果您的特性支持 'write without response' 但不支持 'write',那么您的设备将不会将所需的消息发送回您的应用,因此不会调用 didWriteValuefor()。通常您可以在文档中找到它,或者使用 "LightBlue Explorer" 等蓝牙应用程序来查看您设备的此信息。
根据 Apple Developer Documentation,函数 didWriteValueFor() 在 writeValue() 函数被调用之后被调用。 (参见 https://developer.apple.com/documentation/corebluetooth/cbperipheraldelegate/1518823-peripheral)
我有一个可写的特征,我查找了 https://developer.apple.com/documentation/corebluetooth/cbcharacteristicproperties/1519089-write
中提到的 属性现在当我调用writeValue() 函数时,didWriteValueFor() 函数永远不会被调用,为什么?我认为它与调用 didUpdateValueFor() 函数的 readValue() 函数的结构相同,这对我来说工作正常。 这是我的代码:
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
for characteristic in service.characteristics!{
print(characteristic)
if(characteristic.uuid == TX_CHARACTERISTIC){
elsa.writeValue(dataWithHexString(hex: VALID_GET_VERSION_REQUEST), for: characteristic, type: CBCharacteristicWriteType.withResponse)//calls didWriteValueFor if Type = withResponse
}
if(characteristic.uuid == RX_CHARACTERISTIC){
elsa.setNotifyValue(true, for: characteristic)//calls didUpdateNotificationStateFor
}
}
}
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
guard let data = characteristic.value else { return }
print("\nValue: \(data.toHexEncodedString()) \nwas written to Characteristic:\n\(characteristic)")
if(error != nil){
print("\nError while writing on Characteristic:\n\(characteristic). Error Message:")
print(error as Any)
}
}
如@Paulw11 所述,该值仅在显式读取后写入。我通过在 didWrite() 函数中调用 readValue() 来解决这个问题。
更新的解决方案:
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
elsa.readValue(for: characteristic)
guard let data = characteristic.value else { return }
print("\nValue: \(data.toHexEncodedString()) \nwas written to Characteristic:\n\(characteristic)")
if(error != nil){
print("\nError while writing on Characteristic:\n\(characteristic). Error Message:")
print(error as Any)
}
}
当您调用 writeValue() 时,您可以指定是否需要来自远程设备的响应。在您的情况下,您指定了 CBCharacteristicWriteType.withResponse ,它告诉远程设备它需要发回响应并指示写入是否成功。当远程设备发送响应消息时,这将触发对 didWriteValueFor() 的调用。如果您的设备不发送响应,则不会调用 didWriteValueFor()。您可以在 apple documentation here 中阅读相关内容。您需要 运行 蓝牙嗅探器捕获来确认这一点,但我怀疑您的蓝牙设备没有正确响应 writeValue() 请求。
请注意,每个 BLE 特性都有一组属性来控制特性的行为方式。其中一些属性包括:rear、write、write without response、notify、inform。检查您正在使用的特征的属性,并确保它支持 'write' 属性。如果您的特性支持 'write without response' 但不支持 'write',那么您的设备将不会将所需的消息发送回您的应用,因此不会调用 didWriteValuefor()。通常您可以在文档中找到它,或者使用 "LightBlue Explorer" 等蓝牙应用程序来查看您设备的此信息。