如何在Kotlin多平台项目的iOS端编写预处理(#if)代码?
Kotlin多平台iOS端区分Debug/Release环境的实现方案
你可以不用局限于调用Swift自定义代码,以下几种方案都能实现需求:
方案1:通过Gradle传递编译宏给Kotlin/Native
在iOS模块的Gradle配置中,为Debug和Release构建分别添加编译宏:
kotlin { ios { binaries { framework { debug.get().compilerOpts.add("-Xmacro=DEBUG=true") release.get().compilerOpts.add("-Xmacro=RELEASE=true") } } } }
接着在Kotlin代码中通过@OptionalExpectation读取宏值:
@OptionalExpectation expect const val DEBUG: Boolean class IOSPlatform: Platform { override val name: String get() { val suffix = if (DEBUG) " debug" else " release" return UIDevice.currentDevice.systemName() + suffix + " " + UIDevice.currentDevice.systemVersion } } actual fun getPlatform(): Platform = IOSPlatform()
@OptionalExpectation会让未定义的宏默认取false,适配Release构建场景。
方案2:调用Swift预处理代码(你提到的方法)
如果更熟悉Swift的预处理机制,可先编写Swift工具类:
import Foundation class BuildConfig { static var isDebug: Bool { #if DEBUG return true #else return false #endif } }
再通过Kotlin的expect/actual机制调用:
// 公共模块声明expect函数 expect fun isDebug(): Boolean // iOS模块实现actual函数 actual fun isDebug(): Boolean = BuildConfig.isDebug class IOSPlatform: Platform { override val name: String get() { val suffix = if (isDebug()) " debug" else " release" return UIDevice.currentDevice.systemName() + suffix + " " + UIDevice.currentDevice.systemVersion } } actual fun getPlatform(): Platform = IOSPlatform()
方案3:利用Kotlin/Native构建变体源集
在iOS模块下创建iosMain/debug和iosMain/release目录,分别放置对应构建变体的代码:
- Debug版本代码(iosMain/debug/kotlin/包名/IOSPlatform.kt):
class IOSPlatform: Platform { override val name: String = UIDevice.currentDevice.systemName() + " debug " + UIDevice.currentDevice.systemVersion } actual fun getPlatform(): Platform = IOSPlatform()
- Release版本代码(iosMain/release/kotlin/包名/IOSPlatform.kt):
class IOSPlatform: Platform { override val name: String = UIDevice.currentDevice.systemName() + " release " + UIDevice.currentDevice.systemVersion } actual fun getPlatform(): Platform = IOSPlatform()
最后在Gradle中配置源集与构建变体的关联:
kotlin { ios { sourceSets { val iosMain by getting val iosDebug by creating { dependsOn(iosMain) } val iosRelease by creating { dependsOn(iosMain) } binaries.framework { debug.get().sourceSet(iosDebug) release.get().sourceSet(iosRelease) } } } }
这种方式无需条件判断,构建时会自动加载对应变体的代码。
内容的提问来源于stack exchange,提问作者Grzegorz Adam Hankiewicz
相关产品推荐
相关产品推荐

