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>
This commit is contained in:
km2023
2026-05-20 16:02:28 +08:00
parent ff62b50810
commit 6ed3c555df
4 changed files with 44 additions and 6 deletions

View File

@@ -47,11 +47,28 @@ let sdk = DuooomiBleSDK(config: .init(
// cdnHost: "https://cdn.bowong.cc/", //
// aniWidth: 360, aniHeight: 360, aniFps: "24", // ANI
// frameIntervalMs: 35, // (ms) [0,500] warn clamp
// logLevel: .off, // .off .debug
))
sdk.delegate = self
```
### 日志BleLogLevel
SDK 内部所有日志统一走 `BleLog``print`,分级 `off / error / warn / info / debug`。集成方通过 `config.logLevel` 控制输出:
```swift
//
DuooomiBleSDK(config: .init(apiKey: ..., brand: ..., scanNamePrefix: ...))
// debug BLE RPC opId
DuooomiBleSDK(config: .init(apiKey: ..., brand: ..., scanNamePrefix: ..., logLevel: .debug))
```
- 等级单调:`.warn` 会输出 warn + error`.info` 输出 info + warn + error以此类推。
- **Release 构建因 `#if DEBUG` 条件编译,任何 `logLevel` 都不会输出**(双保险)。
- 日志按 category 分桶:`SDK / Scan / Connect / BLE / RPC / Command / Transfer / Firmware / Protocol / Decode / Config`Xcode console 可按 `[DuooomiBleSDK][<category>]` 过滤。
## SDK 能力范围
- **内置**BLE 协议(扫描/连接/绑定/解绑/播放模式/文件传输/OTA 烧录)+ 固件版本检查

View File

@@ -21,6 +21,9 @@ public struct DuooomiBleConfig {
/// `[0, 500]` warn使 clamp
/// / 35
public let frameIntervalMs: Int
/// SDK `.off` `.warn` `.debug`
/// Release `#if DEBUG` level
public let logLevel: BleLogLevel
public init(
apiHost: URL = URL(string: "https://api.duooomi.com")!,
@@ -31,7 +34,8 @@ public struct DuooomiBleConfig {
aniHeight: Int = 360,
aniFps: String = "24",
scanNamePrefix: String,
frameIntervalMs: Int = 35
frameIntervalMs: Int = 35,
logLevel: BleLogLevel = .off
) {
self.apiHost = apiHost
self.apiKey = apiKey
@@ -41,9 +45,7 @@ public struct DuooomiBleConfig {
self.aniHeight = aniHeight
self.aniFps = aniFps
self.scanNamePrefix = scanNamePrefix
if frameIntervalMs < 0 || frameIntervalMs > 500 {
BleLog.w("frameIntervalMs=\(frameIntervalMs) out of [0,500], will clamp at use site", "Config")
}
self.frameIntervalMs = frameIntervalMs
self.logLevel = logLevel
}
}

View File

@@ -108,6 +108,7 @@ public final class DuooomiBleSDK: NSObject {
// MARK: - Init
public init(config: DuooomiBleConfig) {
BleLog.level = config.logLevel
self.config = config
bleClient = BleClient()
protocolService = BleProtocolService(client: bleClient, frameIntervalMs: config.frameIntervalMs)
@@ -122,7 +123,10 @@ public final class DuooomiBleSDK: NSObject {
super.init()
protocolService.delegate = self
BleLog.i("SDK initialized (apiHost=\(config.apiHost), brand=\(config.brand))", "SDK")
BleLog.i("SDK initialized (apiHost=\(config.apiHost), brand=\(config.brand), logLevel=\(config.logLevel))", "SDK")
if config.frameIntervalMs < 0 || config.frameIntervalMs > 500 {
BleLog.w("frameIntervalMs=\(config.frameIntervalMs) out of [0,500], will clamp at use site", "Config")
}
setupDisconnectHandler()
// UpgradeRecord delegate

View File

@@ -1,28 +1,43 @@
import Foundation
/// SDK `DuooomiBleConfig.logLevel` Release
public enum BleLogLevel: Int {
case off = 0
case error
case warn
case info
case debug
}
enum BleLog {
/// `DuooomiBleSDK.init(config:)` `.off`
static var level: BleLogLevel = .off
static func d(_ message: @autoclosure () -> String, _ category: String = "General") {
#if DEBUG
guard level.rawValue >= BleLogLevel.debug.rawValue else { return }
print("[DuooomiBleSDK][\(category)] \(message())")
#endif
}
static func i(_ message: @autoclosure () -> String, _ category: String = "General") {
#if DEBUG
guard level.rawValue >= BleLogLevel.info.rawValue else { return }
print(" [DuooomiBleSDK][\(category)] \(message())")
#endif
}
static func w(_ message: @autoclosure () -> String, _ category: String = "General") {
#if DEBUG
guard level.rawValue >= BleLogLevel.warn.rawValue else { return }
print("⚠️ [DuooomiBleSDK][\(category)] \(message())")
#endif
}
static func e(_ message: @autoclosure () -> String, _ category: String = "General") {
#if DEBUG
guard level.rawValue >= BleLogLevel.error.rawValue else { return }
print("❌ [DuooomiBleSDK][\(category)] \(message())")
#endif
}
}