具有Objective-C框架的Kotlin多平台/原生互操作性

时间:2019-01-02 11:24:30

标签: kotlin kotlin-interop kotlin-native kotlin-multiplatform

我正在尝试在一个多平台项目中从Kotlin调用Swift / Objective-C代码。调用平台代码没有问题。但是,当我尝试调用某个库(或框架,因为我不是iOS开发人员而不确定如何正确调用它)时,它将失败。 Docs指出,如果导出正确,可以调用Objective-C代码和Swift:

  

Kotlin / Native提供与Objective-C的双向互操作性。如果正确导入到构建中,则可以在Kotlin代码中使用Objective-C框架和库(默认情况下会导入系统框架)。参见例如Gradle插件文档中的“使用cinterop”。如果Swift库的API已通过@objc导出到Objective-C,则可以在Kotlin代码中使用它。尚不支持Pure Swift模块。

但是它没有说明如何正确导入它们。它仅指向描述旧版gradle插件的gradle plugin description。因此它对我不起作用。最后,我发现了某种可能是导入Objective-C代码的方式:

fromPreset(presets.iosX64, 'ios') {
        compilations.main.outputKinds('FRAMEWORK')
        compilations.main {
            cinterops {
                firebase {
                    def pods = '${System.getProperty("user.home")}/Projects/kmpp/iosApp/Pods/'
                    includeDirs '${pods}Firebase/CoreOnly/Sources',
                            '${pods}FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers'
                }
            }
        }
    }

构建可以顺利运行,但是不会导入任何内容。我究竟做错了什么?完全可以导入这样的库吗?

UPD:

here我找到了一个使用cinterop工具的示例,如下所示:

cd samples/gitchurn
../../dist/bin/cinterop -def src/main/c_interop/libgit2.def \
 -compilerOpts -I/usr/local/include -o libgit2

看来cinterop工具应该在我项目的/dist/bin/文件夹中,但是没有这样的文件夹。我在哪里可以获得cinterop工具?

2 个答案:

答案 0 :(得分:1)

我最终在build.gradle的name.add("Name is "+cstr(name)+ " ") 部分

cinterops

结束此 fromPreset(presets.iosX64, 'ios') { // This preset is for iPhone emulator // Switch here to presets.iosArm64 (or iosArm32) to build library for iPhone device compilations.main { outputKinds('FRAMEWORK') cinterops { firebase { defFile "$projectDir/src/iosMain/cinterop/firebase.def" includeDirs { allHeaders "$projectDir/../iosApp/Pods/FirebaseCore/Firebase/Core/Public", "$projectDir/../iosApp/Pods/FirebaseDatabase/Firebase/Database/Public" } compilerOpts "-F$projectDir/../iosApp/Pods/Firebase -F$projectDir/../iosApp/Pods/FirebaseCore -F$projectDir/../iosApp/Pods/FirebaseDatabase" linkerOpts "-F$projectDir/../iosApp/Pods/Firebase -F$projectDir/../iosApp/Pods/FirebaseCore -F$projectDir/../iosApp/Pods/FirebaseDatabase" } } } } 文件:

.def

这是怎么回事? Cocopods框架位于xcode项目的language = Objective-C headers = FirebaseCore.h FirebaseDatabase.h 目录中。浏览该文件夹,您将找到所需的文件。我不确定Pods文件夹中是否有一些标准文件,但将Firebase放置了主头文件。并且包含对它所需的其他头文件的引用...因此,您可以在头部分的Public文件中指定这些文件名。

接下来,您需要指定在哪里可以找到这些文件以及它们所引用的其他文件。您可以在.def.def文件的includeDirs文件中进行操作。我更喜欢build.gradle文件,因为它可以使用变量。因此,您可以选择这些build.gradle文件夹的路径。 (这足以让kotlin查看库api,但是为了能够运行应用程序,您需要编译并链接该库...)

比编译器和链接器需要知道库/框架本身在哪里。因此,您可以在Public中指定框架根文件夹的路径,如果框架是compilerOpts,则linkerOpts会以-F为前缀,如果是库则是-L

答案 1 :(得分:0)

您似乎将要使用cocoapods库。目前,Gradle插件不支持即食鳕鱼。但是可能依赖于您的库可以“手动”配置。您能否分享到您的项目的链接?