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

Android转Swift:Omron BP7000 BLE写入时间失败(错误码128)

修正Omron BP7000时间写入的Swift代码(解决CBATTErrorDomain Code 128)

问题背景

将Android平台下向Omron BP7000血压计写入当前时间的代码转成iOS Swift代码时,触发蓝牙ATT错误:NSError domain: "CBATTErrorDomain" - code: 128。这个错误本质是写入的数据格式不符合外设协议要求。以下是原Android工作代码、你写的Swift代码、两者生成的字节数组对比,以及针对性的修正方案。

原Android工作代码

// 生成时间字节数组的方法
private byte[] getTimeBytes() {
    Calendar calendar = Calendar.getInstance();
    int year = calendar.get(Calendar.YEAR) - 2000; // 取2000年后的偏移量
    int month = calendar.get(Calendar.MONTH) + 1; // 月份从1开始
    int day = calendar.get(Calendar.DAY_OF_MONTH);
    int hour = calendar.get(Calendar.HOUR_OF_DAY);
    int minute = calendar.get(Calendar.MINUTE);
    int second = calendar.get(Calendar.SECOND);
    
    byte[] timeBytes = new byte[7];
    timeBytes[0] = (byte) 0x01; // 命令标识
    timeBytes[1] = (byte) year;
    timeBytes[2] = (byte) month;
    timeBytes[3] = (byte) day;
    timeBytes[4] = (byte) hour;
    timeBytes[5] = (byte) minute;
    timeBytes[6] = (byte) second;
    
    return timeBytes;
}

// 写入操作示例
BluetoothGattCharacteristic characteristic = ...; // 对应时间写入的特征值
characteristic.setValue(getTimeBytes());
gatt.writeCharacteristic(characteristic);

待修正的Swift代码

// 生成时间字节数组的方法
func getTimeBytes() -> Data {
    let calendar = Calendar.current
    let year = calendar.component(.year, from: Date()) - 2000
    let month = calendar.component(.month, from: Date())
    let day = calendar.component(.day, from: Date())
    let hour = calendar.component(.hour, from: Date())
    let minute = calendar.component(.minute, from: Date())
    let second = calendar.component(.second, from: Date())
    
    var timeBytes = [UInt8]()
    timeBytes.append(0x01)
    timeBytes.append(UInt8(year))
    timeBytes.append(UInt8(month))
    timeBytes.append(UInt8(day))
    timeBytes.append(UInt8(hour))
    timeBytes.append(UInt8(minute))
    timeBytes.append(UInt8(second))
    
    return Data(timeBytes)
}

// 写入操作示例
if let characteristic = ... { // 对应时间写入的特征值
    peripheral.writeValue(getTimeBytes(), for: characteristic, type: .withoutResponse)
    // 或尝试.withResponse?
}

字节数组对比(以2024年5月20日14:30:45为例)

  • Android生成的字节数组:[0x01, 0x18, 0x05, 0x14, 0x0E, 0x1E, 0x2D]
    (注:2024-2000=24→0x18;5→0x05;20→0x14;14→0x0E;30→0x1E;45→0x2D)
  • Swift生成的字节数组:[0x01, 0x18, 0x05, 0x14, 0x0E, 0x1E, 0x2D]
    (表面数值一致,但存在写入类型、字节符号性的潜在差异)

错误分析与修正方案

CBATTError 128属于应用层协议错误,核心是数据或写入方式不符合外设要求,以下是具体修复点:

1. 修正蓝牙写入类型

Android的writeCharacteristic默认用带响应的写入(对应Swift的.withResponse),你当前Swift代码用的.withoutResponse可能导致外设无法正确处理请求。
修正代码:

peripheral.writeValue(getTimeBytes(), for: characteristic, type: .withResponse)

2. 统一字节符号性

Android的byte是有符号类型(范围-128127),Swift的`UInt8`是无符号类型(0255)。虽然当前年份偏移量24<127不会触发问题,但为了完全匹配Android的字节格式,建议统一用有符号字节:
修正代码:

// 生成字节数组时改用Int8
let timeBytes: [Int8] = [
    0x01,
    Int8(year),
    Int8(month),
    Int8(day),
    Int8(hour),
    Int8(minute),
    Int8(second)
]
return Data(bytes: timeBytes, count: timeBytes.count)

3. 确认特征值权限

确保目标CBCharacteristic具备WRITE权限,可通过打印验证:

print("Characteristic properties: \(characteristic.properties.rawValue)")
// 输出需包含.write或.writeWithoutResponse

最终修正后的完整Swift代码

func getTimeBytes() -> Data {
    let calendar = Calendar.current
    let now = Date()
    let year = calendar.component(.year, from: now) - 2000
    let month = calendar.component(.month, from: now)
    let day = calendar.component(.day, from: now)
    let hour = calendar.component(.hour, from: now)
    let minute = calendar.component(.minute, from: now)
    let second = calendar.component(.second, from: now)
    
    // 用Int8匹配Android有符号byte格式
    let timeBytes: [Int8] = [
        0x01,
        Int8(year),
        Int8(month),
        Int8(day),
        Int8(hour),
        Int8(minute),
        Int8(second)
    ]
    
    return Data(bytes: timeBytes, count: timeBytes.count)
}

// 写入操作
if let characteristic = targetCharacteristic,
   characteristic.properties.contains(.write) {
    peripheral.writeValue(getTimeBytes(), for: characteristic, type: .withResponse)
} else {
    print("目标特征值不支持写入操作")
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 01:15:11