无法解析 Kotlin Multiplatform 中的 cinterop IOS 导入

Posted

技术标签:

【中文标题】无法解析 Kotlin Multiplatform 中的 cinterop IOS 导入【英文标题】:Unable to resolve cinterop IOS import in Kotlin Multiplatform 【发布时间】:2021-03-19 23:08:37 【问题描述】:

我已按照 Kotlin 文档添加 ios 依赖项。就我而言,依赖项是通过第三方提供的预编译框架。所以我遵循了没有 cocoapod 的框架的案例。

我将 MyFramework.def 文件放在 /src 中

language = Objective-C
modules = MyFramework
package = MyFramework

然后我将以下内容添加到 Kotlin 对象中的 build.gradle.kts ```

ios 
    binaries 
        framework 
            baseName = "shared"
        
    

iosArm64() 
    compilations.getByName("main") 
        val JWBLe by cinterops.creating 
            // Path to .def file
            defFile("src/nativeInterop/cinterop/MyFramework.def")

            compilerOpts("-framework", "MyFramework", "-F/Users/user/Projects/MyFramework/ios/SDK")
        
    

    binaries.all 
        // Tell the linker where the framework is located.
        linkerOpts("-framework", "MyFramework", "-F/Users/user/Projects/MyFramework/ios/SDK")
    

sourceSets 
    val commonMain by getting
    val commonTest by getting 
        dependencies 
            implementation(kotlin("test-common"))
            implementation(kotlin("test-annotations-common"))
        
    
    val androidMain by getting 
        dependencies 
            implementation("com.google.android.material:material:1.2.1")
        
    
    val androidTest by getting 
        dependencies 
            implementation(kotlin("test-junit"))
            implementation("junit:junit:4.13")
        
    
    val iosMain by getting
    val iosTest by getting

然后我构建项目。该库确实被看到了,我看到在外部库中,有一个 shared-cinterop-MyFramework.klib

但是,当我尝试将此包导入到我的代码中时,src/iosMain/kotlin/com.example.testapp.shared/platform.kt 我收到图书馆未解决的错误。看来我还需要在 sourceSets 中添加一些东西?但我不确定。

【问题讨论】:

【参考方案1】:

首先,我注意到 Gradle 脚本不正确。在这种情况下,iosArm64 目标被声明了两次 - 由 target shortcut 和您配置 cinterop 的地方再次声明。为了避免这种重复,最好像这样配置 cinterop:

ios()
    val iosArm = targets.getByName("iosArm64") as  org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
    // A bit dirty cast, but as I'm sure iosArm64 is the Native target, it should be fine. Needed to make highlighting below work as expected.
    iosArm.apply 
        compilations.getByName("main") 
            val JWBLe by cinterops.creating 
                // Path to .def file
                defFile("src/nativeInterop/cinterop/MyFramework.def")

                compilerOpts("-framework", "MyFramework", "-F/Users/user/Projects/MyFramework/ios/SDK")
            
        
        binaries.all 
            // Tell the linker where the framework is located.
            linkerOpts("-framework", "MyFramework", "-F/Users/user/Projects/MyFramework/ios/SDK")
        
    

但是,此调整无助于从 iosMain 访问 cinterop 绑定。在commonizer的当前状态下,只能分享platform libraries。所以无论如何,将所有使用这些绑定的代码移动到src/iosArm64Main 文件夹是目前最好的选择。这里有一个来自官方跟踪器的问题来支持和订阅 - Support commonization of user-defined libraries。

【讨论】:

【参考方案2】:

所以在玩了一段时间后我找到了答案。

为 iosArm64 的模块设置了依赖项,该模块对 iosMain 不可用。

我创建了另一个文件夹 src/iosArm64Main 并将源文件放在那里。此时它能够解析库。

【讨论】:

以上是关于无法解析 Kotlin Multiplatform 中的 cinterop IOS 导入的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin Multiplatform Android Imports 无法解决

无法在 MacBook M1 芯片上构建 Kotlin Multiplatform 移动项目

无法在 Kotlin Multiplatform 项目中引用 kotlinx.cinterop 包

SQLDelight:Kotlin Multiplatform App 中未解决的参考 AndroidSqliteDriver

如何在 kotlin Multiplatform 和 Swift 中使用默认接口实现

Kotlin Multiplatform 中 iOS 应用程序的不同架构