如何将第三方 iOS pod 库添加到 kotlin 原生项目中?收到错误“SharedCode:cinteropAFNetworkingIos 失败”

Sao*_*ood 5 android kotlin gradle-kotlin-dsl kotlin-native kotlin-multiplatform

我创建了 Kotlin 原生项目以在 iOS 和 android 之间共享代码。我对 cocoapods 进行了集成,以便使用 POD 文件在 iOS 项目中使用,项目在 iOS 和 Android 上成功运行,但是当我尝试在 Kotlin 原生项目中使用 iOS pod 库时,我开始收到以下错误。

我知道我必须先从 Xcode 运行 pod install 才能在 Kotlin 本机项目中编译库。

所以 iOS pod 库应该通过 cinterop 进行转换,以便在 Kotlin Native 项目中使用。

我运行下面的命令只是为了检查框架是否成功编译。

./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.
Run Code Online (Sandbox Code Playgroud)

请在下面找到 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)```




Run Code Online (Sandbox Code Playgroud)

Art*_*rev 6

我只是尝试了这些步骤,并设法使用 CocoaPods 插件通过 AFNetworking 框架的工作互操作来扩展示例。这些是我的步骤:

  1. 克隆项目并检出step-008分支后,以这种方式编辑 build.gradle.kts:将 CocoaPods 插件添加到plugins部分 asid("org.jetbrains.kotlin.native.cocoapods")binaries从 iOSTarget 规范块中删除整个块。应该这样做,因为 cocoaPods 插件自己创建框架,我们应该避免重复(参见讨论)。而不是那个块,添加cocoapods规范。脚本的这一部分应如下所示:
iOSTarget("ios") {}
    version = "1.0.0"
    cocoapods {
        summary = "This is sample Summary"
        homepage = "Home URL"

        pod("AFNetworking", "~> 3.2.0")
    }
Run Code Online (Sandbox Code Playgroud)
  1. 然后,执行 Gradle 任务podspec为您的框架生成 podspec。这应该在/SharedCode/目录内完成,就像上一个一样。如果没有出现任务,则表示 CocoaPods 插件没有正确应用。
  2. 当 podspec 准备好后,我们可以从 Xcode 项目中使用它。为此,请打开/native/KotlinIOS/目录,并在那里创建 Podfile。我将这些内容用于:
use_frameworks!

platform :ios, '9.0'

target 'KotlinIOS' do
    pod 'SharedCode', :path => '../../SharedCode'
end
Run Code Online (Sandbox Code Playgroud)

这里重要的部分是名称与我们的框架名称相对应,相对路径指向build.gradle.kts第一步包含的地方。创建 Podfile 后,pod install从终端使用此处安装 Pod (应安装CocoaPods )。

  1. 现在打开KotlinIOS.xcworkspace用 Xcode生成。在那里,还应该修复一件事。此时 KotlinIOS 项目设置为仅在/SharedCode/build/Xcode-frameworks/目录中搜索框架,但 CocoaPods 不会在那里放置任何内容。因此,在左侧面板上选择 KotlinIOS,打开 Build Settings 选项卡并找到 Search Paths -> Framework Search Paths。按 + 并将 $(inherited) 添加到列表中,以使 CocoaPods 安装的框架可用。
  2. 现在,从 Xcode 执行 Build。之后,在您的 Kotlin IDE 中,AFNetworking 包应该可用。要导入它,请使用import cocoapods.AFNetworking.*. 第一次它可能需要使缓存和重新启动无效,以使其正确地看到这个包。

我希望这将有所帮助。如果本说明中有不清楚的地方,请发表评论。