You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

蓝牙BLE中Central发送带响应写请求后无法接收Peripheral回复

蓝牙BLE带响应写请求:Central端无法接收Peripheral回复的问题排查

已正常实现的特征读取功能

当前BLE特征读取功能运行正常,相关代码如下:

Central端发送读请求

func readCharacteristicValue() {
    if let peripheral = connectedPeripheral, let characteristic = targetCharacteristic {
        peripheral.readValue(for: characteristic)
    }
}

Peripheral端处理读请求

func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveRead request: CBATTRequest) {
    
    // 根据服务调用不同逻辑
    switch request.characteristic.uuid {
        
    case Constants.uuid.AuthService:
            let authenticationInstance = PAuthentication.pAuthentication
            authenticationInstance.responseToReadRequest(request: request, peripheralManager: peripheralManager, clearServiceCharacteristic: clearServiceCharacteristic)
        
        case Constants.uuid.OtherService: print("Other implementation")
        
        default: print("Nothing")
    }
    
}

Central端接收读响应

func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?){
    // 处理错误
    if let error = error {
        print("Error reading characteristic value: \(error)")
    }

    // 根据响应的特征处理不同逻辑
    switch characteristic.uuid {
        
    case Constants.uuid.AuthService:
            let authenticationInstance = CAuthentication.cAuthentication
            authenticationInstance.responceFromReadRequest(characteristic: characteristic, disconnect: disconnect)
        
        default:
            print("Nothing")
    }
}

带响应写请求的问题描述

实现带响应的写请求时出现异常:Central端发送带响应的写请求后,Peripheral端能正常接收并处理请求,但Central端无法收到Peripheral的回复数据。

Central端写请求代码

func writeStringToCharacteristic(_ string: String) {
    if let data = string.data(using: .utf8), let peripheral = connectedPeripheral, let characteristic = targetCharacteristic {
        peripheral.writeValue(data, for: characteristic, type: .withResponse)
    }
}

Peripheral端处理写请求代码

func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveWrite requests: [CBATTRequest]) {
     for request in requests {
         if request.characteristic == characteristic {
             if let value = request.value {
                 // 处理Central发送的数据示例
                 let receivedString = String(data: value, encoding: .utf8)
                 print("Received data from Central: \(receivedString ?? "")")
                 if (receivedString == "Auth"){
                     
                     var dataToSend:Data?
                     if let name = SharedData.shared.AuthData["name"],
                        let surname = SharedData.shared.AuthData["surname"],
                        let date = SharedData.shared.AuthData["date"] {
                        dataToSend = "\(name), \(surname), \(date)".data(using: .utf8)
                         // 准备通过蓝牙特征发送数据
                     } else {
                         print("One or more values are missing")
                     }
                     
                     request.value = dataToSend
                     peripheralManager.respond(to: request, withResult: .success)
                     // 无法将回复送达Central
                 }
             }
         }
     }
 }

可能的原因及排查方向

  • 写请求响应逻辑误解:BLE协议中,带响应的写请求(.withResponse)的CBATTRequest.value字段仅用于读请求返回数据,写请求的响应仅告知Central写操作成功/失败,不会主动附带数据。若需在处理写请求后返回数据,必须使用**通知(Notify)或指示(Indicate)**机制。
  • 特征属性配置不全:检查目标特征的属性,需同时开启write(或writeWithoutResponse)和notify/indicate属性,否则Peripheral无法主动推送数据给Central。
  • Central端未订阅特征通知:若要接收Peripheral主动推送的数据,Central必须先调用setNotifyValue(true, for: characteristic)订阅目标特征的通知/指示。
  • Central端未实现写操作回调:带响应的写请求的结果(成功/失败)需通过peripheral(_:didWriteValueFor:error:)回调接收,而非didUpdateValueFor(该回调用于接收读响应和通知数据),若未实现此回调会误以为没收到回复。

修正示例

Peripheral端修改:处理写请求后发送通知

func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveWrite requests: [CBATTRequest]) {
    for request in requests {
        if request.characteristic == characteristic {
            if let value = request.value {
                let receivedString = String(data: value, encoding: .utf8)
                print("Received data from Central: \(receivedString ?? "")")
                if receivedString == "Auth" {
                    var dataToSend: Data?
                    if let name = SharedData.shared.AuthData["name"],
                       let surname = SharedData.shared.AuthData["surname"],
                       let date = SharedData.shared.AuthData["date"] {
                        dataToSend = "\(name), \(surname), \(date)".data(using: .utf8)
                    } else {
                        print("One or more values are missing")
                    }
                    
                    // 先回复写操作成功状态
                    peripheralManager.respond(to: request, withResult: .success)
                    
                    // 若有数据需要返回,通过通知发送给已订阅的Central
                    if let data = dataToSend, let targetChar = characteristic {
                        peripheralManager.updateValue(data, for: targetChar, onSubscribedCentrals: nil)
                    }
                }
            }
        }
    }
}

Central端配套修改

  1. 订阅目标特征的通知:
// 连接Peripheral并发现特征后执行
if let peripheral = connectedPeripheral, let characteristic = targetCharacteristic {
    peripheral.setNotifyValue(true, for: characteristic)
}
  1. 实现写操作结果回调:
func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) {
    if let error = error {
        print("Write operation failed: \(error)")
        return
    }
    print("Write operation succeeded")
}
  1. 保留原didUpdateValueFor回调接收通知数据(与读响应共用):
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?){
    if let error = error {
        print("Error receiving data: \(error)")
        return
    }
    
    switch characteristic.uuid {
    case Constants.uuid.AuthService:
        let authenticationInstance = CAuthentication.cAuthentication
        authenticationInstance.responceFromReadRequest(characteristic: characteristic, disconnect: disconnect)
    default:
        print("Nothing")
    }
}

内容的提问来源于stack exchange,提问作者Emanuele Mele

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 18:57:02