km2023
ed7de42e61
fix(sdk): transferMedia 入口立即把 transferProgress 归零
...
旧实现里 transferProgress 只在 transferFile() 内部才置 0,但
transferMedia 要先走 validateMediaFormat → aniConverter.convert →
getRemoteFileSize → prepareTransfer 这条数秒级异步链,期间字段还停
留在上次结束的 100。集成方 UI 一接上观察就看到旧值 100,体感像「上
次进度被带过来」。
修法:transferMedia 在 connectedDevice 守卫通过后立即 transferProgress = 0,
delegate 立即收到 didUpdateProgress(0);后续 transferFile() 内部的 = 0
因 didSet 的 oldValue 守卫被自然跳过,不会重复广播。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-20 16:02:41 +08:00
km2023
6ed3c555df
feat(sdk): 日志等级 logLevel 配置化(默认 .off,对外发布完全静默)
...
BleLog 之前所有调用都无条件 print(Debug 包),集成方没法关。新增
public enum BleLogLevel(off/error/warn/info/debug),通过
DuooomiBleConfig.logLevel 传入,DuooomiBleSDK.init 第一行写入
BleLog.level。默认 .off 保证对外集成默认静默,排查时显式开 .debug。
保留 #if DEBUG 兜底,Release 任何 level 都不输出。
frameIntervalMs 越界 warn 从 DuooomiBleConfig.init 挪到
DuooomiBleSDK.init 内、level 设置之后,避免在 level 写入前丢日志。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-20 16:02:28 +08:00
km2023
09088121b5
feat(sdk): 帧间隔 frameIntervalMs 配置化(默认 35ms,[0,500] clamp)
...
DuooomiBleConfig 新增 frameIntervalMs,BleProtocolService 构造期注入。
顺手清死代码 FrameConstants.frameIntervalNanos、修 sendFrames 0.035 字面量
(统一走 config)。demo 加可调输入框 + UserDefaults 持久化。
越界 warn 不抛错,使用点 min/max 兜底。
设计稿:docs/superpowers/specs/2026-05-20-frame-interval-config-design.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-20 14:02:04 +08:00
km2023
a15403ae36
feat(sdk): upgradeFirmware 下发前校验电量 ≥40%,不足抛 .batteryTooLow
...
OTA 烧录前主动拉新鲜 getDeviceInfo 取实时电量,<40% 直接以
.batteryTooLow(current:required:) 失败、不发任何字节,防烧录中途断电变砖。
新增常量 minBatteryForUpgrade=40;烧录体抽出私有 performFirmwareTransfer。
README 补可用方法/属性汇总表。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-19 17:19:23 +08:00
km2023
4bc8fdb64d
feat(sdk): 绑定时上报设备 log 到 update-metadata 并内聚双层绑定
...
- 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 >
2026-05-18 16:25:55 +08:00
km2023
97e5b8359a
feat(sdk): 重命名 owner→brand 并在硬绑前校验设备品牌
...
- DuooomiBleConfig.owner → brand(语义:设备品牌名),HTTP header x-owner 不变
- bind() 前置 verifyBrand:缺 deviceInfo 先 getDeviceInfo,与 config.brand 严格匹配,不一致主动断连并抛 .brandMismatch
- README 抹除软绑/对账/UpgradeRecord 等内部实现细节,仅保留厂商面向的公开 API(功能代码完全保留)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-09 11:51:17 +08:00
km2023
d5729a1a41
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 >
2026-05-08 14:46:41 +08:00
km2023
f4a32bb7e8
fix(ble): discover all services then filter; some firmware rejects scoped discovery
...
When discoverServices is called with a specific UUID list, certain firmware
returns an empty service array even though the requested service exists on
the device. Match expo-duooomi-app's behavior (discoverAllServicesAndCharacteristics)
by passing nil and filtering in the delegate callback.
Also log discovered service UUIDs to aid future debugging.
2026-05-06 11:43:06 +08:00
km2023
c3a726fc02
feat: add setPlayMode SDK API with isActivated precondition
2026-05-06 10:42:09 +08:00
km2023
7aec09be2a
feat: extend BindPayload with optional loop field; add setPlayMode service
...
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-05-06 10:38:19 +08:00
km2023
4b1017df42
feat: add optional loop field to DeviceInfo
2026-05-06 10:34:34 +08:00
km2023
be851b05ec
feat: add PlayMode enum (single=0, loop=1)
2026-05-06 10:31:36 +08:00
km2023
f42944bb58
feat: 增加媒体格式校验,支持 JPEG、PNG、GIF、MP4、WebM、WebP 格式
2026-04-20 15:40:22 +08:00
km2023
1a7bbdc625
feat: 重写 SDK 支持 iOS 12.2,移除 async/await 和 Combine
...
- 所有公开 API 改为 completion handler (Result<T, Error>)
- 状态通知改为 DuooomiBleSDKDelegate 协议
- 移除 Sendable、@MainActor、AsyncStream、CheckedContinuation
- 网络请求改为 URLSession.dataTask 回调
- BLE 通信改为 delegate + 闭包模式
- deployment target 降至 iOS 12.2
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-16 16:59:39 +08:00
km2023
79af43cdef
feat: apiHost 改为 api.duooomi.com,ANI 转换参数可配置
...
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com >
2026-04-16 14:24:02 +08:00
km2023
920c24456a
feat:sdk 增加判断是否有新固件可用
2026-04-13 18:41:46 +08:00
km2023
ba0a80e921
feat: Sdk 封装
2026-04-10 16:15:53 +08:00
km2023
7d9ff3081d
demo app + SDK updates:\n- Add direct ANI transfer (prepare -> transfer)\n- Add firmware update flow (fetch latest w/ x-api-key, OTA transfer)\n- Extract x-api-key to NetworkConstants\n- Rename example app to demo; move folder and entry to DemoApp\n- Switch from SPM package dependency to local framework target\n- Enable automatic Info.plist generation for framework target\n- Add placeholder test to satisfy SwiftPM test target\n- Regenerate XcodeGen project (demo.xcodeproj)
2026-04-09 18:41:56 +08:00