Compose Multiplatform「IOS-Beta」初次体验

1,075 阅读4分钟

了解 Compose Multiplatform 已经比较久了,之前尝试过 compose-desktop 与 Android 的 jp-compose还是比较一致的。最近了解到 Compose-IOS 已经发布了 beta 版本,应该算比较稳定了,所以来尝试一下。

配置环境

开发 IOS app 必须在 MacOS 下面开发,所以此项目的前提是你必须有一台 Mac 设备。

在创建第一个 Kotlin Multiplatform 应用程序之前,您需要为 KMP 开发设置一个环境。

安装必要的工具

检查环境

要确保一切按预期工作,请安装并运行 KDoctor 工具:

brew install kdoctor
  • 安装完毕后再执行命令
kdoctor

如果环境没有问题则应该是如下信息:

❯ kdoctor
Environment diagnose (to see all details, use -v option):
[✓] Operation System
[✓] Java
[✓] Android Studio
[✓] Xcode
[✓] CocoaPods

Conclusion:
  ✓ Your operation system is ready for Kotlin Multiplatform Mobile Development!

如果有问题,则会在某一项上打,然后有相关错误信息,按照提示操作就行。

可能出现的问题及解决方案

使用向导创建项目

  1. 打开 [Kotlin Multiplatform](Kotlin Multiplatform Wizard | JetBrains) 向导 。
  2. 在 New project 选项卡上,将项目名称更改为 “FirstKMP”,将项目 ID 更改为 “com.example.kmp”。
  3. 确保已选择 Android 和 iOS 选项。
  4. 单击 Download 按钮并解压缩生成的存档。

导入工程

同步结束后我们来看下工程结构:

  • /composeApp 是用于在 Compose Multiplatform 应用程序中共享代码的目录。 它包含几个子文件夹:

    • commonMain 是用于所有目标通用的代码。
    • 其他文件夹是用于仅在文件夹名称中指示的平台上编译的 Kotlin 代码。 例如,上图的 androidMainiosMain 分别用来处理自己平台的独有业务逻辑。另外还可以创建其他平台,如:webMain、desktopMain 等。
  • /iosApp 包含 iOS 应用程序。即使你在使用 Compose Multiplatform 共享 UI, 你仍然需要这个 iOS 应用程序的入口点。这也是你应该为项目添加 SwiftUI 代码的地方。

commonMain 源集使用通用的 Kotlin 代码,平台源集使用特定于每个目标的 Kotlin 代码。Kotlin/JVM用于 androidMaindesktopMainKotlin/Native 用于 iosMain

commonMain 源代码在构建为 Android library 时被视为 Kotlin/JVM。在构建为 iOS framwork 时被视为 Kotlin/Native

运行应用

可以在 Android、iOS虚拟机或真机上运行该应用程序。不需要按任何特定顺序运行应用程序,从您最熟悉的平台开始。

运行 Android app

对于 Android 开发人员应该是无比熟悉,不需要你做任何事,直接选择需要运行的目标设备,然后点击“运行”按钮就行

image.png

运行 IOS app

有时候可能因为Xcode环境问题,这里的iosApp 会标记着一个红色的x号,提示找不到设别,或者其他关于Xcode的问题,此时可以直接点击iosApp module 下的 iosApp.xcodeproj ,可以直接用Xcode 来打开编译。

然后点击菜单Edit Configrations... 指定一个 Execution target,如:iOS 15,然后就可以点击“运行”按钮运行了。

image.png

这样我们的第一个 demo app 就成功运行了,对比下 ios 与 Android 的差异就是屏幕显示的系统版本分别是 iOS 18.0Android 34,我们来看看这部分的差异如何实现的。

iOS 与 Andriod 的差异实现

interface Platform {
    val name: String
}

expect fun getPlatform(): Platform

这是在 commonMain 的一个文件,它定义了一个接口和一个 top level 函数,这跟我们之前接触的 kotlin 一样。不同的是 getPlaform 方法前有一个关键字 expect,这个关键字在 KMP 中很重要,它的声明表示公共代码预期每个平台的不同实际actual实现。在此处其作用于函数。但是,它也可以应用于类、对象、注释等。(有关更多信息,请参阅此处)

class Greeting {
    private val platform = getPlatform()

    fun greet(): String {
        return "Hello, ${platform.name}!"
    }
}

我们来看看调用部分的代码,这几行代码很简单,相信大家都看得懂。调用getPlatform()是希望得到一个Platform对象实例,而因为getPlatform()前面有 expect 关键字,所以它在不同的平台上有不同的代码实现,我们继续看。

// Platform.android.kt
class AndroidPlatform : Platform {
    override val name: String = "Android ${Build.VERSION.SDK_INT}"
}

actual fun getPlatform(): Platform = AndroidPlatform()
// Platform.ios.kt
class IOSPlatform: Platform {
    override val name: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion
}

actual fun getPlatform(): Platform = IOSPlatform()

Platform.android.kt 文件在 androidMain 模块, Platform.ios.kt 在 iosMain模块。可以看到它们分别有不同的 actual 函数,然后当然也有着不同的实现,在此处就是分别获取了不同平台的版本号。这样便轻松的实现了各自独占逻辑,还是比较容易理解的吧。

Demo 展示

最近玩羽毛球比较多,大家希望组织一些小对抗,增加运动的趣味性。所以就有了羽毛球选手随机抽签、分组对抗的需求,需求比较简单于是就手撸了一个。

t1.gif

这里只展示了 iOS 的效果,实际 Android 与 iOS 是一模一样的,就不展示了。

源码在这,有需要的可以自取。

最后,希望此篇文章对帮助大家入门 Compose for iOS 有帮助。