我创建了Kotlin本机项目以在iOS和android之间共享代码。我对cocoapods进行了集成,以便使用POD文件在iOS项目中使用,Project成功在iOS和Android上运行,但是当我尝试在Kotlin原生项目,下面开始出现错误。
我知道我必须先从Xcode运行pod install才能在Kotlin本机项目中编译库。
SO iOS pod库应该通过cinterop进行转换,以便在Kotlin Native Project中使用。
我运行以下命令只是为了检查框架是否成功编译。
./ 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文件中找到。
build.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)```
答案 0 :(得分:4)
我只是尝试了这些步骤,并使用CocoaPods插件通过AFNetworking框架的有效互操作来扩展this示例。这些是我的步骤:
step-008
分支后,以这种方式编辑build.gradle.kts:将CocoaPods插件作为plugins
添加到id("org.jetbrains.kotlin.native.cocoapods")
部分,并删除整个{{1 }}来自iOSTarget规范块。这样做是因为cocoaPods插件自行创建了框架,我们应该避免重复(请参见discussion)。代替该块,添加binaries
规范。脚本的这一部分应如下所示:cocoapods
iOSTarget("ios") {}
version = "1.0.0"
cocoapods {
summary = "This is sample Summary"
homepage = "Home URL"
pod("AFNetworking", "~> 3.2.0")
}
为框架生成podspec。与上一个目录一样,此操作应在podspec
目录内完成。如果未显示任务,则表明CocoaPods插件未正确应用。/SharedCode/
目录,然后在此处创建Podfile。我使用这些内容的原因是:/native/KotlinIOS/
这里的重要部分是名称与我们的框架名称相对应,并且第一步中相对路径指向包含use_frameworks!
platform :ios, '9.0'
target 'KotlinIOS' do
pod 'SharedCode', :path => '../../SharedCode'
end
的位置。创建Podfile之后,请在终端上使用build.gradle.kts
在此处安装Pod(CocoaPods应该为installed)。
pod install
。在那里,应该再解决一件事。目前,KotlinIOS项目设置为仅在KotlinIOS.xcworkspace
目录中搜索框架,但是CocoaPods不会在此放置任何内容。因此,在左侧面板上选择KotlinIOS,打开Build Settings选项卡,然后在其中找到Search Paths-> Framework Search Paths。按+并在列表中添加$(继承),以提供CocoaPods安装的框架。/SharedCode/build/Xcode-frameworks/
。第一次可能需要使缓存无效并重新启动,以使其正确看到此程序包。我希望这会有所帮助。如果本说明中有不清楚的地方,请发表评论。
答案 1 :(得分:0)
添加此答案是因为有些用户想知道为什么 IDE 建议 在 IOS 通用代码的情况下没有出现。原因是 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 的支持。
这是我已经提出的问题,如果可能的话,请投票以使其重要。