如何将第三方iOS Pod库添加到Kotlin本机项目中?出现错误“ SharedCode:cinteropAFNetworkingIos失败”

时间:2020-02-08 11:51:10

标签: android kotlin gradle-kotlin-dsl kotlin-multiplatform kotlin-native

我创建了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)```




2 个答案:

答案 0 :(得分:4)

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

  1. 克隆项目并检出step-008分支后,以这种方式编辑build.gradle.kts:将CocoaPods插件作为plugins添加到id("org.jetbrains.kotlin.native.cocoapods")部分,并删除整个{{1 }}来自iOSTarget规范块。这样做是因为cocoaPods插件自行创建了框架,我们应该避免重复(请参见discussion)。代替该块,添加binaries规范。脚本的这一部分应如下所示:
cocoapods
  1. 然后,执行Gradle任务iOSTarget("ios") {} version = "1.0.0" cocoapods { summary = "This is sample Summary" homepage = "Home URL" pod("AFNetworking", "~> 3.2.0") } 为框架生成podspec。与上一个目录一样,此操作应在podspec目录内完成。如果未显示任务,则表明CocoaPods插件未正确应用。
  2. 准备好podspec后,我们可以在Xcode项目中使用它。为此,请打开/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)。

  1. 现在打开使用Xcode生成的pod install。在那里,应该再解决一件事。目前,KotlinIOS项目设置为仅在KotlinIOS.xcworkspace目录中搜索框架,但是CocoaPods不会在此放置任何内容。因此,在左侧面板上选择KotlinIOS,打开Build Settings选项卡,然后在其中找到Search Paths-> Framework Search Paths。按+并在列表中添加$(继承),以提供CocoaPods安装的框架。
  2. 现在,从Xcode执行Build。之后,在您的Kotlin IDE中,AFNetworking软件包应该可用。要导入它,请使用/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 的支持。

这是我已经提出的问题,如果可能的话,请投票以使其重要。

https://youtrack.jetbrains.com/issue/KT-42319