- bind(userId:) 内聚为硬绑 + getVersion + 软绑 + updateMetadata 一次原子调用, 软绑失败自动硬解绑回滚 + 清状态;集成方无需感知双层绑定 - fetchLatestFirmware 简化为对账上报 + checkUpgrade 两步,不再重复软绑 - VersionInfo 增加 log: [String: Any]?,走 JSONSerialization 解析(放弃 Codable); SDK 暴露只读 versionLog,断连/解绑/软绑回滚时清空 - ShipmentSnDeviceService 新增 updateMetadata(sn:data:),抽出 performPOST 共享 HTTP 编排,新增 postAnyJSON 支持 [String: Any] body - 老固件不返回 log → versionLog == nil → 自动跳过 updateMetadata,前向兼容 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
48 lines
1.8 KiB
Swift
48 lines
1.8 KiB
Swift
import Foundation
|
||
|
||
public struct VersionInfo: Equatable {
|
||
public let version: String
|
||
/// 命令类型标识,设备可能返回 Int (如 7) 或 String (如 "0x07")
|
||
public let type: String
|
||
/// 设备运行日志,BLE 响应中 `log` 字段对应的任意 JSON 对象;缺失/非对象时为 nil。
|
||
/// SDK 不解析其内部结构,原样透传给 `update-metadata` 接口。
|
||
public let log: [String: Any]?
|
||
|
||
public init(version: String, type: String, log: [String: Any]? = nil) {
|
||
self.version = version
|
||
self.type = type
|
||
self.log = log
|
||
}
|
||
|
||
public static func == (lhs: VersionInfo, rhs: VersionInfo) -> Bool {
|
||
guard lhs.version == rhs.version, lhs.type == rhs.type else { return false }
|
||
return NSDictionary(dictionary: lhs.log ?? [:]).isEqual(to: rhs.log ?? [:])
|
||
}
|
||
}
|
||
|
||
extension VersionInfo {
|
||
/// 从设备 BLE 响应字节流(已剥离 0 字节)解析。
|
||
/// type 字段兼容 Int / String 两种返回形态;log 字段缺失/非对象时返回 nil。
|
||
static func parse(from data: Data) throws -> VersionInfo {
|
||
let cleaned = data.filter { $0 != 0 }
|
||
let object = try JSONSerialization.jsonObject(with: cleaned)
|
||
guard let json = object as? [String: Any] else {
|
||
throw DuooomiBleError.transferFailed("VersionInfo: top-level not an object")
|
||
}
|
||
|
||
let version = (json["version"] as? String) ?? ""
|
||
|
||
let type: String
|
||
if let s = json["type"] as? String {
|
||
type = s
|
||
} else if let n = json["type"] as? NSNumber {
|
||
type = "\(n.intValue)"
|
||
} else {
|
||
type = ""
|
||
}
|
||
|
||
let log = json["log"] as? [String: Any]
|
||
return VersionInfo(version: version, type: type, log: log)
|
||
}
|
||
}
|