我创建了Kotlin原生项目,在iOS和android之间共享代码。我对cocoapods进行了集成,以便在iOS项目中使用POD文件,该项目在iOS和Android上成功运行,但当我尝试在Kotlin原生项目中使用iOS POD库时,我开始出现以下错误。
我知道我必须先从Xcode运行pod安装,以便在静态编程语言原生项目中编译库。
SOiOSpod库应该通过cinterop转换,以便在静态编程语言原生项目中使用。
我运行下面的命令只是为了检查框架编译是否成功。
./gradlew:SharedCode:packForXCode
得到了这个错误
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':SharedCode:cinteropAFNetworkingIos'.
> Cannot perform cinterop processing for AFNetworking: cannot determine headers location.
Probably the build is executed from command line.
Note that a Kotlin/Native module using CocoaPods dependencies can be built only from Xcode.
请查找下面的Gradle文件。
建造。Gradle.kts
plugins {
kotlin("multiplatform")
kotlin("native.cocoapods")
}
kotlin {
//select iOS target platform depending on the Xcode environment variables
val iOSTarget: (String, KotlinNativeTarget.() -> Unit) -> KotlinNativeTarget =
if (System.getenv("SDK_NAME")?.startsWith("iphoneos") == true)
::iosArm64
else
::iosX64
iOSTarget("ios") {
binaries {
framework("Shared") {
baseName = "SharedCode"
}
}
}
jvm("android")
sourceSets["commonMain"].dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-common")
}
sourceSets["androidMain"].dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib")
}
version = "1.0.0"
cocoapods {
summary = "This is sample Summary"
homepage = "Home URL"
pod("AFNetworking", "~> 3.2.0")
}
}
val packForXcode by tasks.creating(Sync::class) {
group = "build"
//selecting the right configuration for the iOS framework depending on the Xcode environment variables
val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
val framework = kotlin.targets.getByName<KotlinNativeTarget>("ios").binaries.getFramework(mode)
inputs.property("mode", mode)
dependsOn(framework.linkTask)
val targetDir = File(buildDir, "xcode-frameworks")
from({ framework.outputDirectory })
into(targetDir)
doLast {
val gradlew = File(targetDir, "gradlew")
gradlew.writeText("#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$@\n")
gradlew.setExecutable(true)
}
}
tasks.getByName("build").dependsOn(packForXcode)```
我只是尝试了这些步骤,并使用CocoaPods插件通过AFNetworking框架的互操作扩展了这个示例。以下是我的步骤:
step-008
分支后,编辑build。格拉德尔。这样做:将CocoaPods插件添加到plugins
部分,作为id(“org.jetbrains.kotlin.native.CocoaPods”)
并从iOSTarget规范块中删除整个二进制文件。应该这样做,因为cocoaPods插件自己创建框架,我们应该避免重复(参见讨论)。添加cocoapods
specification,而不是该块。脚本的这一部分应该如下所示:
iOSTarget("ios") {}
version = "1.0.0"
cocoapods {
summary = "This is sample Summary"
homepage = "Home URL"
pod("AFNetworking", "~> 3.2.0")
}
use_frameworks!
platform :ios, '9.0'
target 'KotlinIOS' do
pod 'SharedCode', :path => '../../SharedCode'
end
这里重要的一点是,该名称对应于我们的框架名称,以及包含build的位置上的相对路径点。格拉德尔。kts
从第一步开始。创建pod文件后,使用终端上的pod install
在此处安装pod(应安装CocoaPods)。
我希望这会有所帮助。如果本说明中有不清楚之处,请予以评论。
添加这个答案是因为一些用户想知道为什么在IOS通用代码中没有IDE建议。原因是仍然没有完成IOS代码的通用化,这意味着iosMain将无法工作—它将编译,但没有显示建议或导入。要使其正常工作,必须指定特定的源集。
例如
kotlin {
android()
iosX64()
cocoapods {
// Configure fields required by CocoaPods.
summary = "Kotlin Multiplatform Firebase login sample"
homepage = "https://github.com/worstkiller/firebaseloginkmm"
pod("FirebaseAuth")
frameworkName = "sharedFramework"
}
sourceSets {
val commonMain by getting {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:${Versions.coroutines}")
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
val androidMain by getting {
dependencies {
implementation("com.google.firebase:firebase-auth:${Versions.firebase_auth_android}")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:${Versions.coroutines}")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:${Versions.viewmodel}")
}
}
val androidTest by getting {
dependencies {
implementation(kotlin("test-junit"))
implementation("junit:junit:${Versions.junit}")
}
}
val iosX64Main by getting
val iosX64Test by getting
configure(listOf(iosX64Main)) {
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core-native:${Versions.coroutines_native}")
}
}
}
}
在上面的代码块中,我只添加了对iosX64源代码集的支持,这意味着它只能在机器上工作。您可以类似地添加对iosArm64的支持。
这是我已经提出的一个问题,如果可能的话,投票决定它是否有价值。
https://youtrack.jetbrains.com/issue/KT-42319