Swift中如何解码非UTF8字节为字符串?Freestyle Libre传感器数据解析
Swift 解码 Freestyle Libre 传感器 NFC 数据方案
1. 修正现有读取代码
你当前代码中success回调的参数名被误写为str,实际上readSingleBlock接口返回的成功值是原始二进制Data类型,不是UTF8字符串,直接打印会显示为内存地址或者不可读的符号,先调整代码:
case .iso15693(let tag): // 读取单个块数据,如需获取血糖值需要读取块3及之后的块 tag.readSingleBlock(requestFlags: .highDataRate, blockNumber: 0, resultHandler: { result in switch result { case .success(let rawData): // rawData为8字节原始二进制数据,直接处理即可 print("读取到的原始字节: \(rawData.map { String(format: "%02hhx", $0) })") // 调用解码方法 let decodedValue = decodeLibreBlock(data: rawData, blockNumber: 0) print(decodedValue) case .failure(let error): print("读取失败: \(error.localizedDescription)") } })
2. 基础解码逻辑实现
2.1 字节读取工具扩展
首先给Data添加扩展方法,方便按小端序读取16位无符号整数(Freestyle Libre的数值存储默认采用小端序):
extension Data { func readUInt16LE(at offset: Int) -> UInt16 { guard offset + 1 < count else { return 0 } return UInt16(self[offset]) | (UInt16(self[offset + 1]) << 8) } }
2.2 块数据解码逻辑
不同块号存储的内容不同:
- 块0:存储传感器序列号、生产信息等基础数据
- 块3~块26:存储实时血糖、历史血糖原始值
- 块27及之后:存储校准参数、传感器状态信息
举个实时血糖值解码的示例(对应块3的前2字节):
func decodeGlucoseValue(from data: Data) -> Double { // 读取原始16位血糖数值 let rawGlucose = data.readUInt16LE(at: 0) // 通用校准公式,校准系数可从传感器校准块读取,此处为通用默认值 let glucoseValue = (Double(rawGlucose) - 40) * 0.1 // 转换为mmol/L单位,如需mg/dL则乘以18 return glucoseValue }
传感器返回响应参考

内容的提问来源于stack exchange,提问作者Solano Todeschini
相关产品推荐
相关产品推荐

