如何将KMM库日志共享至iOS(Swift)及Android应用
实现KMM日志向Swift应用的传递
针对你需要将KMM库的日志共享到Swift端的需求,这里提供几种对应Swift代理/通知模式的KMM实现方案,结合你正在使用的Napier日志框架来落地:
方案1:Kotlin接口(对应Swift协议)回调代理
这个方案完全对应Swift的代理模式,逻辑直观,适合单条日志的实时传递:
- 在KMM的Common模块定义日志回调接口和级别枚举
interface LogCallback { fun onLog(message: String, level: LogLevel) } enum class LogLevel { VERBOSE, DEBUG, INFO, WARNING, ERROR }
- 自定义Napier日志引擎,将日志转发到回调接口
class CallbackLogger(private val callback: LogCallback) : Napier.LogEngine { override fun performLog(priority: Napier.LogLevel, tag: String?, throwable: Throwable?, message: String?) { val logContent = buildString { append(tag?.let { "[$it] " } ?: "") append(message ?: "") throwable?.let { append("\n${it.stackTraceToString()}") } } callback.onLog(logContent, mapNapierLevel(priority)) } private fun mapNapierLevel(napierLevel: Napier.LogLevel): LogLevel { return when(napierLevel) { Napier.LogLevel.VERBOSE -> LogLevel.VERBOSE Napier.LogLevel.DEBUG -> LogLevel.DEBUG Napier.LogLevel.INFO -> LogLevel.INFO Napier.LogLevel.WARNING -> LogLevel.WARNING Napier.LogLevel.ERROR -> LogLevel.ERROR } } }
- 在KMM核心业务类中提供回调设置入口
class PosTerminalManager { var logCallback: LogCallback? = null init { Napier.base(CallbackLogger(object : LogCallback { override fun onLog(message: String, level: LogLevel) { logCallback?.onLog(message, level) } })) } }
- Swift端实现对应协议并绑定
class AppLogHandler: LogCallback { func onLog(message: String, level: LogLevel) { // 这里可以执行日志收集逻辑:写入本地文件、上报服务器等 print("KMM 日志 [\(level.rawValue)]: \(message)") } } // 使用时绑定 let terminalManager = PosTerminalManager() terminalManager.logCallback = AppLogHandler()
方案2:Kotlin Flow响应式日志流
这个方案对应Swift的Combine/AsyncSequence,适合批量日志处理或实时订阅场景:
- 在Common模块定义日志流和数据结构
import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.asSharedFlow class LogFlowManager { private val _logFlow = MutableSharedFlow<LogEntry>() val logFlow = _logFlow.asSharedFlow() data class LogEntry(val message: String, val level: LogLevel) enum class LogLevel { VERBOSE, DEBUG, INFO, WARNING, ERROR } }
- 实现Flow版Napier日志引擎
class FlowLogger(private val logFlowManager: LogFlowManager) : Napier.LogEngine { override fun performLog(priority: Napier.LogLevel, tag: String?, throwable: Throwable?, message: String?) { val logContent = buildString { append(tag?.let { "[$it] " } ?: "") append(message ?: "") throwable?.let { append("\n${it.stackTraceToString()}") } } val logLevel = when(priority) { Napier.LogLevel.VERBOSE -> LogFlowManager.LogLevel.VERBOSE Napier.LogLevel.DEBUG -> LogFlowManager.LogLevel.DEBUG Napier.LogLevel.INFO -> LogFlowManager.LogLevel.INFO Napier.LogLevel.WARNING -> LogFlowManager.LogLevel.WARNING Napier.LogLevel.ERROR -> LogFlowManager.LogLevel.ERROR } kotlinx.coroutines.GlobalScope.launch { logFlowManager._logFlow.emit(LogFlowManager.LogEntry(logContent, logLevel)) } } }
- 在KMM核心类中初始化
class PosTerminalManager { val logFlowManager = LogFlowManager() init { Napier.base(FlowLogger(logFlowManager)) } }
- Swift端订阅日志流
let terminalManager = PosTerminalManager() // 用Async/Await订阅处理 Task { for await logEntry in terminalManager.logFlowManager.logFlow { print("KMM 流式日志 [\(logEntry.level.rawValue)]: \(logEntry.message)") // 执行自定义日志收集逻辑 } }
注意事项
- 替换Napier默认引擎时,确保在KMM库初始化阶段完成,避免日志遗漏
- Swift端处理回调或订阅时,注意用弱引用避免内存泄漏
- 日志级别枚举在KMM和Swift端会自动映射,保持定义一致即可
内容的提问来源于stack exchange,提问作者lucgian841
相关产品推荐
相关产品推荐

