diff --git a/README.md b/README.md index 24a809b..5f53310 100644 --- a/README.md +++ b/README.md @@ -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][]` 过滤。 + ## SDK 能力范围 - **内置**:BLE 协议(扫描/连接/绑定/解绑/播放模式/文件传输/OTA 烧录)+ 固件版本检查 diff --git a/Sources/DuooomiBleSDK/DuooomiBleConfig.swift b/Sources/DuooomiBleSDK/DuooomiBleConfig.swift index cb4a87e..06e13ef 100644 --- a/Sources/DuooomiBleSDK/DuooomiBleConfig.swift +++ b/Sources/DuooomiBleSDK/DuooomiBleConfig.swift @@ -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 } } diff --git a/Sources/DuooomiBleSDK/DuooomiBleSDK.swift b/Sources/DuooomiBleSDK/DuooomiBleSDK.swift index e33a9ea..3075a90 100644 --- a/Sources/DuooomiBleSDK/DuooomiBleSDK.swift +++ b/Sources/DuooomiBleSDK/DuooomiBleSDK.swift @@ -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 通知 diff --git a/Sources/DuooomiBleSDK/Utils/BleLogger.swift b/Sources/DuooomiBleSDK/Utils/BleLogger.swift index 037c12c..98dabf2 100644 --- a/Sources/DuooomiBleSDK/Utils/BleLogger.swift +++ b/Sources/DuooomiBleSDK/Utils/BleLogger.swift @@ -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 } } -