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:
km2023
2026-05-08 14:46:41 +08:00
parent f4a32bb7e8
commit d5729a1a41
24 changed files with 2349 additions and 880 deletions

View File

@@ -0,0 +1,44 @@
import Foundation
///
/// - `success`: ==
/// - `versionMismatch`: failure
/// - `nil`: 30 TTL
public enum UpgradeOutcome: String, Codable, Equatable {
case success
case versionMismatch = "version_mismatch"
}
/// OTA `(sn, firmwareId)`
/// RN `bleStore.upgradeRecords` 1:1
public struct UpgradeRecord: Codable, Equatable {
public let sn: String
public let firmwareId: String
public let fromVersion: String
public let targetVersion: String
/// OTA RN `Date.now()`
public let triggeredAt: Int64
public let reported: Bool
public let reportedAt: Int64?
public let outcome: UpgradeOutcome?
public init(
sn: String,
firmwareId: String,
fromVersion: String,
targetVersion: String,
triggeredAt: Int64,
reported: Bool = false,
reportedAt: Int64? = nil,
outcome: UpgradeOutcome? = nil
) {
self.sn = sn
self.firmwareId = firmwareId
self.fromVersion = fromVersion
self.targetVersion = targetVersion
self.triggeredAt = triggeredAt
self.reported = reported
self.reportedAt = reportedAt
self.outcome = outcome
}
}