使用来自 Kotlin/Native 和 Gradle 的 Apple 依赖项,更具体地说是 SwiftUI

Posted

技术标签:

【中文标题】使用来自 Kotlin/Native 和 Gradle 的 Apple 依赖项,更具体地说是 SwiftUI【英文标题】:Use Apple dependencies, more specifically SwiftUI, from Kotlin/Native with Gradle 【发布时间】:2021-05-30 21:12:16 【问题描述】:

如何在 Kotlin/Native 或 Kotlin 多平台项目中使用 Gradle 将 Apple 依赖项添加到 Kotlin/Native 模块?

我不熟悉 Apple 和 Xcode 开发——我写了一点 Swift,但没有为 Xcode 项目配置额外的依赖项,所以如果我在这里有新手误解,请原谅。

Kotlin/Native is interoperable with Objective-C and Swift。在我在线浏览的许多示例项目中,Kotlin 被设置为用作 Apple (ios) 模块的共享库。但是 Apple 依赖项中的定义也可以从 Kotlin 代码中调用,就像 Java Maven 依赖项如何添加到 Gradle 构建脚本然后被 Kotlin 代码调用一样。

Name Translation section 中说:

platform.* 用于预配置系统框架的包

在使用 IntelliJ IDEA 中的 Kotlin Multiplatform Mobile Application 选项创建的项目中,此类定义包含在 iosMain 模块的 kotlin 文件夹中的 platform 包下 shared 模块中。

但是,SwiftUI 不存在。更具体地说,就我而言,我正在尝试使用 SwiftUI 在 Kotlin 中直接构建 UI。目前是否有可能,然后如何使 SwiftUI“系统框架”也包含在内?

这是我在shared 模块中的build.gradle.kts 供参考:

import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget

plugins 
    kotlin("multiplatform") version "1.4.30"


group = "my.group.name"
version = "1.0-SNAPSHOT"

kotlin 
    ios 
        binaries 
            framework 
                baseName = "shared"
            
        
    
    sourceSets 
        val commonMain by getting
        val commonTest by getting 
            dependencies 
                implementation(kotlin("test-common"))
                implementation(kotlin("test-annotations-common"))
            
        
        val iosMain by getting
        val iosTest by getting
    


val packForXcode by tasks.creating(Sync::class) 
    group = "build"
    val mode = System.getenv("CONFIGURATION") ?: "DEBUG"
    val sdkName = System.getenv("SDK_NAME") ?: "iphonesimulator"
    val targetName = "ios" + if (sdkName.startsWith("iphoneos")) "Arm64" else "X64"
    val framework = kotlin.targets.getByName<KotlinNativeTarget>(targetName).binaries.getFramework(mode)
    inputs.property("mode", mode)
    dependsOn(framework.linkTask)
    val targetDir = File(buildDir, "xcode-frameworks")
    from( framework.outputDirectory )
    into(targetDir)


tasks.getByName("build").dependsOn(packForXcode)

【问题讨论】:

【参考方案1】:

Kotlin/Native 不与纯 Swift 互操作。从您链接的文档中:

“Kotlin/Native 提供了与 Objective-C 的双向互操作性” ...“如果使用 @objc 将其 API 导出到 Objective-C,则可以在 Kotlin 代码中使用 Swift 库。还没有纯 Swift 模块支持。”

可以使用@objc Swift 注释将Swift 编写为与Objc 互操作,这将对Swift 代码应用一些约束。 SwiftUI 绝对是纯 Swift,无法导入 Kotlin。

我还建议,即使可能,从 Kotlin 编写 SwiftUI 也可能会带来更糟糕的开发体验,因为 Xcode 在启用 SwiftUI 预览等方面投入了大量工作。如果有任何正式的 Kotlin 努力iOS 的 UI,我猜这将是 Compose 的一次尝试。 JetBrains 可能会在 AppCode 中为 SwiftUI 做出一些努力,但我猜想 SwiftUI + Kotlin 还需要很长时间。 Kotlin/Native 首先需要直接的 Swift 互操作,这已经讨论过,但 AFAIK 尚未启动。

总结,我会在 Xcode 中使用 Swift 编写 SwiftUI,然后与其他共享的 Kotlin 讨论 UI“下方”的逻辑。

【讨论】:

以上是关于使用来自 Kotlin/Native 和 Gradle 的 Apple 依赖项,更具体地说是 SwiftUI的主要内容,如果未能解决你的问题,请参考以下文章

Kotlin Native (iOS),使用 CValuesRef 和 CCCrypt

Kotlin 一统天下?Kotlin/Native 开始支持 iOS 和 Web 开发

如何使用 Kotlin/native 生成​​依赖于另一个的 .framework?

使用 Kotlin/Native,我如何执行外部 OS 可执行文件或 $PATH 命令并与其 stdin、stdout 和 stderr 流交互?

[译]Kotlin/Native v0.2 发布啦

Kotlin JVM 和 Kotlin Native 有啥区别?