![](/img/trans.png)
[英]How to configure an iOS Application for Kotlin Multiplatform in Android Studio?
[英]How to speed up iOS app builds of Kotlin Multiplatform from Android Studio
我有一个 KMP 项目,其中包含 iOS 应用程序、Android 应用程序和共享的 KMP 模块。 当我尝试从 Android Studio 构建 iOS 应用程序(以便能够对其进行调试)时,构建成功。 ☺️
问题是构建总是(当你更改代码时)需要大约 12 分钟⏰。 当您调试并经常测试给定代码是否有效时,这是很长的时间。 花费在构建上的 90% 的时间用于运行这些任务:
> Task :kmpcorelib:linkDebugFrameworkIosArm64
> Task :kmpcorelib:linkDebugFrameworkIosX64
> Task :kmpcorelib:linkKMPCoreDebugFrameworkIosArm64
> Task :kmpcorelib:linkKMPCoreDebugFrameworkIosX64
> Task :kmpcorelib:linkKMPCoreReleaseFrameworkIosArm64
> Task :kmpcorelib:linkKMPCoreReleaseFrameworkIosX64
> Task :kmpcorelib:linkReleaseFrameworkIosArm64
> Task :kmpcorelib:linkReleaseFrameworkIosX64
我的问题是:有没有办法在不运行所有这些任务的情况下如何在 iOS 模拟器上运行应用程序?
不知道工作室为什么要链接RELEASE版本的框架。
我也不明白为什么它在 X64 模拟器上运行时必须运行iOSArm64
变体。
运行linkDebugFrameworkIosArm64
和linkKMPCoreDebugFrameworkIosArm64
有什么区别,不是重复吗?
PS:我通过点击 Android Studio 中的默认配置来运行 iOS buld,而不是一些自定义的 gradle 脚本。
这是 KMP build.gradle 的样子:
plugins {
id("com.android.library")
kotlin("multiplatform")
kotlin("native.cocoapods")
kotlin("plugin.serialization") version "1.5.0"
id("com.prof18.kmp.fatframework.cocoa") version "0.0.1"
id("io.gitlab.arturbosch.detekt")
id("maven-publish")
}
version = "1.3.11"
group = "com.betsys.kmpcorelib"
val podName = "KMPCore"
detekt {
autoCorrect = true
config = files("$rootDir/config/detekt.yml")
baseline = file("$rootDir/config/baseline.xml")
input = files("src/commonMain/kotlin")
reports {
html.enabled = true
xml.enabled = true
txt.enabled = true
}
}
// If you want to build iOS app from Android Studio - you have to put this config to comment - it somehow breaks the iOS build
fatFrameworkCocoaConfig {
fatFrameworkName = podName
outputPath = "$rootDir/../cocoapods"
versionName = "1.16.1"
}
val ktorVersion = "1.5.4"
val napierVersion = "1.4.1"
val koinVersion = "3.0.1"
val kotlinxVersion = "1.4.1"
val kotlinxDatetime = "0.1.1"
kotlin {
// We cant use simple ios() target now, since it doesnt support Arm32 architecture
// For that reason we have specify each target explicitly
// Same for folders with iOS code. We havet to use duplicit iosX64Main etc. instead of one iosMain folder
ios("ios") {
binaries.framework(podName)
}
android {
publishLibraryVariants("debug")
publishLibraryVariantsGroupedByFlavor = true
}
sourceSets {
val commonMain by getting {
dependencies {
implementation("io.ktor:ktor-client-core:$ktorVersion")
implementation("io.ktor:ktor-client-logging:$ktorVersion")
implementation("io.ktor:ktor-client-mock:$ktorVersion")
implementation("io.ktor:ktor-client-serialization:$ktorVersion")
implementation("io.ktor:ktor-client-websockets:$ktorVersion")
api("io.insert-koin:koin-core:$koinVersion")
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinxVersion-native-mt")
api("org.jetbrains.kotlinx:kotlinx-datetime:$kotlinxDatetime")
api("com.ionspin.kotlin:bignum:0.3.1-SNAPSHOT")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.2.0")
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
implementation( "io.mockk:mockk-common:1.11.0")
implementation("com.ionspin.kotlin:bignum:0.3.1-SNAPSHOT")
}
}
val androidMain by getting {
dependencies {
implementation("io.ktor:ktor-client-android:$ktorVersion")
implementation("com.google.android.material:material:1.3.0")
implementation("io.ktor:ktor-client-okhttp:$ktorVersion")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlinxVersion")
implementation("com.jakewharton.timber:timber:4.7.1")
}
}
val androidTest by getting {
dependencies {
implementation(kotlin("test-junit"))
implementation("junit:junit:4.13.2")
implementation("io.mockk:mockk:1.11.0")
}
}
val iosMain by getting {
dependencies {
implementation("io.ktor:ktor-client-ios:$ktorVersion")
}
}
val iosTest by getting
}
}
android {
compileSdkVersion(30)
sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
defaultConfig {
minSdkVersion(19)
targetSdkVersion(30)
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
}
}
packagingOptions {
excludes.add("META-INF/*.kotlin_module")
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().all {
kotlinOptions {
jvmTarget = "1.8"
}
}
}
val packForXcode by tasks.creating(Sync::class) {
val targetDir = File(buildDir, "xcode-frameworks")
/// selecting the right configuration for the iOS
/// framework depending on the environment
/// variables set by Xcode build
val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
val sdkName: String? = System.getenv("SDK_NAME")
val isiOSDevice = sdkName.orEmpty().startsWith("iphoneos")
val framework = kotlin.targets
.getByName<org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget>(
if (isiOSDevice) {
"iosArm64"
} else {
"iosX64"
}
)
.binaries.getFramework(mode)
inputs.property("mode", mode)
dependsOn(framework.linkTask)
from({ framework.outputDirectory })
into(targetDir)
println("Build Folder => $targetDir")
/// generate a helpful ./gradlew wrapper with embedded Java path
doLast {
val gradlew = File(targetDir, "gradlew")
gradlew.writeText(
"#!/bin/bash\n"
+ "export 'JAVA_HOME=${System.getProperty("java.home")}'\n"
+ "cd '${rootProject.rootDir}'\n"
+ "./gradlew \$@\n"
)
gradlew.setExecutable(true)
}
}
tasks.build.dependsOn("packForXCode")
Android Studio 中的“默认配置”(例如, assemble
或build
gradle 任务)将构建所有“构建”任务,其中包括 Z1BDF605991920DB11CBDF8508204C4EB4 发布框架和 Arm4 架构的链接。
请注意您在build.gradle.kts
文件中获得的packForXcode
任务? 当您想要为 iOS 应用程序(至少在本地)构建 KMM 模块时,这就是您想要调用的内容。 使用该任务将只构建您需要的架构和配置(例如,您的模拟器上的X64
和DEBUG
),您很快就会发现它要快得多。 作为 Xcode 项目的构建步骤的一部分,它应该在运行脚本阶段被调用。
如果您在 Android Studio 中创建新项目时使用 Kotlin 多平台应用程序模板,我相信这应该已自动添加到您的 Xcode 项目中。
您可以在此处阅读更多相关信息:了解 KMM 项目结构 |Kotlin 多平台移动文档
我使用此任务为 iOS 构建更改:
./gradlew :shared:compileKotlinIosSimulatorArm64
工作很快
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.