Kotlin/Native 开发 Apple Framework 教程

Viewed 0

Kotlin/Native 开发 Apple framework——教程

Kotlin/Native 提供与 Swift/Objective-C 的双向互操作性,允许在 Kotlin 代码中使用 Objective-C framework 和库,以及在 Swift/Objective-C 代码中使用 Kotlin 模块。本教程将指导你创建自己的 framework,并学习如何在 macOS 和 iOS 上的 Swift/Objective-C 应用程序中集成 Kotlin/Native 代码。

本教程内容包括:

  • 创建一个 Kotlin 库并将其编译为 framework
  • 检查生成的 Swift/Objective-C API 代码
  • 在 Objective-C 中使用 framework
  • 在 Swift 中使用 framework

对于小型项目,可以使用命令行生成 Kotlin framework,但对于大型项目,推荐使用构建系统如 Gradle,以提高可伸缩性。Kotlin/Native 通过 Kotlin 多平台插件支持 Gradle 构建系统。注意,如果使用 Mac 并需要开发 iOS 或其他 Apple 平台应用,需先安装 Xcode Command Line Tools。

创建一个 Kotlin 库

首先,创建一个 Kotlin 库,Kotlin/Native 编译器会将其编译为适用于 macOS 和 iOS 的 framework,包含所有必要的声明和二进制文件。

步骤:

  1. src/nativeMain/kotlin 目录中创建 lib.kt 文件,并添加以下库代码:
package example

object Object {
    val field = "A"
}

interface Interface {
    fun iMember() {}
}

class Clazz : Interface {
    fun member(p: Int): ULong? = 42UL
}

fun forIntegers(b: Byte, s: UShort, i: Int, l: ULong?) { }
fun forFloats(f: Float, d: Double?) { }

fun strings(str: String?) : String {
    return "That is '$str' from C"
}

fun acceptFun(f: (String) -> String?) = f("Kotlin/Native rocks!")
fun supplyFun() : (String) -> String? = { "$it is cool!" }
  1. 更新 build.gradle(.kts) 文件。以 Kotlin DSL 为例:
plugins {
    kotlin("multiplatform") version "2.1.21"
}

repositories {
    mavenCentral()
}

kotlin {
    iosArm64("native") {
        binaries {
            framework {
                baseName = "Demo"
            }
        }
    }
}

tasks.wrapper {
    gradleVersion = "8.10"
    distributionType = Wrapper.DistributionType.ALL
}

binaries 块配置生成动态或共享库。Kotlin/Native 支持多种 Apple 目标平台,如 iosArm64iosX64iosSimulatorArm64macosX64macosArm64,可根据需要替换 Gradle 函数。

  1. 运行 linkDebugFrameworkNative Gradle 任务来构建 framework。使用命令 ./gradlew linkDebugFrameworkNative,生成的 framework 位于 build/bin/native/debugFramework 目录。也可以使用 linkNative 任务生成调试和发布变体。

生成的 Framework 头文件

每个 framework 变体都包含一个头文件,位于 build/bin/native/debugFramework/Demo.framework/Headers 目录中。头文件独立于目标平台,包含 Kotlin 代码的定义。

Kotlin/Native 运行时声明

头文件定义 Kotlin 运行时声明,例如 KotlinBase 基类(继承自 NSObject)以及集合和异常的包装器。集合类型映射到 Swift/Objective-C 中的相似类型:Kotlin List 映射到 Swift Array 和 Objective-C NSArrayMutableList 映射到 NSMutableArraySet 映射到 Swift Set 和 Objective-C NSSetMutableSet 映射到 NSMutableSetMap 映射到 Swift Dictionary 和 Objective-C NSDictionaryMutableMap 映射到 NSMutableDictionary

Kotlin 数值与 NSNumber

头文件包含 Kotlin/Native 数字类型与 NSNumber 的映射。基类在 Objective-C 中称为 DemoNumber,在 Swift 中称为 KotlinNumber,继承自 NSNumber。每个 Kotlin 数字类型都有对应的子类(如 KotlinByteKotlinUByte 等),提供创建实例和提取值的方法。

Kotlin 中的类与对象

Kotlin 类、接口和对象映射到 Swift/Objective-C。例如,Interface 映射为 @protocolClazzObject 映射为 @interface,并带有前缀如 Demo。可空返回值类型如 ULong? 转换为 DemoULong

Kotlin 中的全局声明

所有全局函数转化为 Objective-C 中的 DemoLibKt 类和 Swift 中的 LibKt 类。Kotlin String 透明映射到 Objective-C NSString*Unit 映射到 void。原生类型直接映射,可空原生类型映射到 Kotlin<TYPE>* 类型。高阶函数如 acceptFunsupplyFun 支持 Objective-C 块和 Swift 闭包。

垃圾回收与引用计数

Swift 和 Objective-C 使用自动引用计数(ARC),而 Kotlin/Native 有自己的垃圾回收器,并与 Swift/Objective-C ARC 集成。无需额外步骤管理 Kotlin/Native 实例的生命周期,未使用对象会自动清理。

在 Objective-C 中使用代码

在 Objective-C 中调用 framework,创建 main.m 文件示例:

#import <Foundation/Foundation.h>
#import <Demo/Demo.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        [DemoObject.shared field];

        DemoClazz* clazz = [[ DemoClazz alloc] init];
        [clazz memberP:42];

        [DemoLibKt forIntegersB:1 s:1 i:3 l:[DemoULong numberWithUnsignedLongLong:4]];
        [DemoLibKt forIntegersB:1 s:1 i:3 l:nil];

        [DemoLibKt forFloatsF:2.71 d:[DemoDouble numberWithDouble:2.71]];
        [DemoLibKt forFloatsF:2.71 d:nil];

        NSString* ret = [DemoLibKt acceptFunF:^NSString * _Nullable(NSString * it) {
            return [it stringByAppendingString:@" Kotlin is fun"];
        }];

        NSLog(@"%@", ret);
        return 0;
    }
}

Kotlin 对象通过 .shared 类属性访问单例,类实例使用 allocinit 创建,全局函数作为 DemoLibKt 的类方法调用。

在 Swift 中使用代码

在 Swift 中使用 framework,创建 main.swift 文件示例:

import Foundation
import Demo

let kotlinObject = Object.shared
let field = Object.shared.field

let clazz = Clazz()
clazz.member(p: 42)

LibKt.forIntegers(b: 1, s: 2, i: 3, l: 4)
LibKt.forFloats(f: 2.71, d: nil)

let ret = LibKt.acceptFun { "\($0) Kotlin is fun" }
if (ret != nil) {
    print(ret!)
}

Swift 中,Kotlin 对象通过 Object.shared 访问,函数和属性名称直接映射,类型如 String 透明转换,支持传递闭包。

将 framework 连接到 iOS 项目

生成的 framework 可以作为依赖添加到 iOS 项目中,有多种自动化方法可供选择,根据项目需求进行设置。

下一步做什么

  • 了解更多关于与 Objective-C 的互操作性。
  • 查看 Kotlin 中与 C 的互操作性实现。
  • 参考 Kotlin/Native 作为动态库的教程。
0 Answers