无法在 Kotlin Multiplatform 中解析 cinterop IOS 导入
Unable to resolve cinterop IOS import in Kotlin Multiplatform
我已按照 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 添加一些东西?但我不确定。
经过一番尝试,我找到了答案。
为 iosArm64 的模块设置了依赖项,该模块不适用于 iosMain。
我创建了另一个文件夹 src/iosArm64Main 并将源文件放在那里。那时它能够解析库。
首先,我注意到 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, it can share only platform libraries. So anyway, moving all code utilizing those bindings into the src/iosArm64Main
folder is the best option available at the moment. Here go an issue from the official tracker to upvote and subscribe - Support commonization of user-defined libraries.
我已按照 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 添加一些东西?但我不确定。
经过一番尝试,我找到了答案。
为 iosArm64 的模块设置了依赖项,该模块不适用于 iosMain。
我创建了另一个文件夹 src/iosArm64Main 并将源文件放在那里。那时它能够解析库。
首先,我注意到 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, it can share only platform libraries. So anyway, moving all code utilizing those bindings into the src/iosArm64Main
folder is the best option available at the moment. Here go an issue from the official tracker to upvote and subscribe - Support commonization of user-defined libraries.