feat(sdk): OTA 升级流程对齐 expo + 拆 extension 文件分层 + 秘钥本地化
主要改动: - 新增 fetchLatestFirmware/upgradeFirmware/tryReportPendingUpgrade 三段 OTA 接口,对齐 expo bindDeviceWithOrchestration 行为 - bind 仅做硬绑+getVersion,软绑/对账上报/拉最新固件搬到 fetchLatestFirmware 内部串;软绑失败自动硬解回滚 - UpgradeRecord 复合主键 (sn, firmwareId) 持久化 + sn 级 in-flight 互斥 - DuooomiBleSDKDelegate 新增 didUpdateUpgradeRecords,集成方 可观察对账上报结果(reported/outcome 状态) - DuooomiBleSDK 主类按职责拆 5 个 extension 文件,公开 API 不变 - TargetFirmware 简化为只取必要字段 + 新增 forceUpgrade - scanNamePrefix 改为必填 String - demo 秘钥移至本地 DemoSecrets.swift (gitignored) - README 重写:完整 OTA 流程示例 + 上报状态判定表 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -16,8 +16,21 @@ struct DemoApp: App {
|
||||
}
|
||||
|
||||
/// ViewModel 包装 SDK callback API,通过 DuooomiBleSDKDelegate 驱动 UI 更新。
|
||||
class DemoViewModel: NSObject, ObservableObject, DuooomiBleSDKDelegate {
|
||||
let sdk: DuooomiBleSDK
|
||||
final class DemoViewModel: NSObject, ObservableObject, DuooomiBleSDKDelegate {
|
||||
|
||||
// MARK: - SDK Config(demo 内可改,持久化到 UserDefaults)
|
||||
|
||||
@Published var configOwner: String {
|
||||
didSet { defaults.set(configOwner, forKey: Self.keyOwner) }
|
||||
}
|
||||
@Published var configApiKey: String {
|
||||
didSet { defaults.set(configApiKey, forKey: Self.keyApiKey) }
|
||||
}
|
||||
@Published var configScanPrefix: String {
|
||||
didSet { defaults.set(configScanPrefix, forKey: Self.keyScanPrefix) }
|
||||
}
|
||||
|
||||
// MARK: - SDK State (driven by delegate)
|
||||
|
||||
@Published var btState: ConnectionState = .idle
|
||||
@Published var connectedDevice: DiscoveredDevice? = nil
|
||||
@@ -27,11 +40,63 @@ class DemoViewModel: NSObject, ObservableObject, DuooomiBleSDKDelegate {
|
||||
@Published var isActivated: Bool = false
|
||||
@Published var transferProgress: Int = 0
|
||||
@Published var error: String? = nil
|
||||
@Published var upgradeRecords: [UpgradeRecord] = []
|
||||
|
||||
@Published private(set) var sdk: DuooomiBleSDK
|
||||
|
||||
// MARK: - Internals
|
||||
|
||||
private let defaults = UserDefaults.standard
|
||||
private static let keyOwner = "demo.config.owner"
|
||||
private static let keyApiKey = "demo.config.apiKey"
|
||||
private static let keyScanPrefix = "demo.config.scanPrefix"
|
||||
|
||||
/// demo 调试默认值(仅当 UserDefaults 没存过时使用)。秘钥从 DemoSecrets 读,避免泄露到仓库。
|
||||
private static let defaultOwner = DemoSecrets.owner
|
||||
private static let defaultApiKey = DemoSecrets.apiKey
|
||||
private static let defaultScanPrefix = DemoSecrets.scanNamePrefix
|
||||
|
||||
override init() {
|
||||
sdk = DuooomiBleSDK(config: .init(apiKey: ""))
|
||||
let d = UserDefaults.standard
|
||||
let owner = d.string(forKey: Self.keyOwner) ?? Self.defaultOwner
|
||||
let apiKey = d.string(forKey: Self.keyApiKey) ?? Self.defaultApiKey
|
||||
let scanPrefix = d.string(forKey: Self.keyScanPrefix) ?? Self.defaultScanPrefix
|
||||
|
||||
self.configOwner = owner
|
||||
self.configApiKey = apiKey
|
||||
self.configScanPrefix = scanPrefix
|
||||
|
||||
self.sdk = DuooomiBleSDK(config: .init(
|
||||
apiKey: apiKey,
|
||||
owner: owner,
|
||||
scanNamePrefix: scanPrefix
|
||||
))
|
||||
|
||||
super.init()
|
||||
sdk.delegate = self
|
||||
// 初次加载 SDK 持久化的 records(之前历史升级 / 待对账)
|
||||
upgradeRecords = sdk.upgradeRecords
|
||||
}
|
||||
|
||||
/// demo 内修改配置后调用:重新创建 SDK 实例并迁移 delegate。
|
||||
func reloadSDK() {
|
||||
let new = DuooomiBleSDK(config: .init(
|
||||
apiKey: configApiKey,
|
||||
owner: configOwner,
|
||||
scanNamePrefix: configScanPrefix
|
||||
))
|
||||
new.delegate = self
|
||||
self.sdk = new
|
||||
// 重置展示状态
|
||||
btState = .idle
|
||||
connectedDevice = nil
|
||||
discoveredDevices = []
|
||||
deviceInfo = nil
|
||||
version = ""
|
||||
isActivated = false
|
||||
transferProgress = 0
|
||||
error = nil
|
||||
upgradeRecords = new.upgradeRecords
|
||||
}
|
||||
|
||||
// MARK: - DuooomiBleSDKDelegate
|
||||
@@ -64,6 +129,10 @@ class DemoViewModel: NSObject, ObservableObject, DuooomiBleSDKDelegate {
|
||||
transferProgress = progress
|
||||
}
|
||||
|
||||
func sdk(_ sdk: DuooomiBleSDK, didUpdateUpgradeRecords records: [UpgradeRecord]) {
|
||||
upgradeRecords = records
|
||||
}
|
||||
|
||||
func sdk(_ sdk: DuooomiBleSDK, didEncounterError error: String?) {
|
||||
self.error = error
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user