Use Compose to realize the dynamic island effect on iOS

foreword

At last year's DevFest's Compose Camp event, two lecturers, fundroid and Zhu Jiang, took everyone to use Compose to realize the effect of the smart island

But the Smart Island is a feature of iOS after all. Just this year, KotlinConf announced that Compose-iOS is already in alpha, so what if we transplant the Smart Island effect that has been implemented with Compose to iOS?

It’s a beautiful thing to think about, just do it, and see what it takes to migrate the code from Jetpack Compose to Compose Multiplatform, and what cost it will cost

Show results

First look at the effect, you can see that the animation effect of the Smart Island switch is basically realized, which is basically the same as the effect on Android

Implementation steps

Environment configuration

To develop with Compose MultiPlatform, the following environment is required

  • XCode
  • Android Studio
  • Kotlin Multiplatform Mobile plugin
  • Cocoapods dependency manager

In fact, it is consistent with the environment required by Kotlin Multiplatform. The most troublesome thing may be the installation of Cocoapods. You can check the KMM documentation for installing Cocoapods: Set up an environment to work with CocoaPods

In addition, you can also kdoctorcheck whether the environment configuration is correct by command

brew install kdoctor // 安装 kdoctor
kdoctor // 检查

If all environments are configured correctly, you will see the following output

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

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

create project

The Compose Multiplatform project is actually adding some Compose content to the KMM project, and there are still a lot of template codes. We can directly use the project template provided by JetBrains to generate the project: compose-multiplatform-ios-android- template

如图所示,其实就是一个 KMM 工程的结构,android 项目的入口是 androidApp,iOS 项目的入口是 iosApp,共享代码放在 shared 模块

在 shared 模块中,各个平台共享代码放在 commonMain 目录中,而各个平台的定制代码则放在 androidMain 与 iosMain 中

在这里主要的不同在于,android 平台直接返回了一个 Composable 函数,供 android 层调用,而 iOS 平台则返回了一个 UIViewController

代码移植

在项目创建完成后,接下来就是代码移植的工作了。移植过程可以说是非常简单,基本上不用做任何改动,Jetpack Compose 项目就可以迁移成 Compose Multiplatform 项目

在我迁移过程中碰到的唯一不同在于资源文件的处理,如下所示,R 文件引用方式需要修改成字符串方式引用

// Jetpack Compose
Image(
    painterResource(R.drawable.icon_cover),
    "music cover",
    Modifier
        .size(animationData.musicImageSize)
        .clip(RoundedCornerShape(animationData.musicImageCorner))
)

// Compose Multiplatform
Image(
    painterResource("icon_cover.xml"),
    "music cover",
    Modifier
        .size(animationData.musicImageSize)
        .clip(RoundedCornerShape(animationData.musicImageCorner))
)

除此之外,两者的状态管理,布局,动画等 api 是完全一致的,可以直接复用代码

经过以上步骤,迁移就完成了,直接运行 androidApp 与 iosApp 就可以得到文章开始展示的效果了

正在处理中的问题

当然,现在 Compose Multiplatform 还处在 alpha 阶段,并不是说已经可以用于生产了,还有不少问题正在处理中

待支持的功能

图片来源:Compose Multiplatform on iOS by: Sebastian Aigner and Nikita Lipsky

可以看出,Compose Multiplatform 还是有不少细节问题要处理的

性能问题

我们打开 XCode 的 instruments 然后运行 app,就可以得到运行的 trace 文件,统计出运行次数较多或者比较耗时的方法

p7.jpg

可以看出,耗时方法有相当一部分是 GC 相关的,当 GC 暂停发生时,会冻结所有对象,自然也会影响 UI 的渲染,导致卡顿

好消息是 Kotlin 正在优化 GC,期望将 GC 暂停控制在 1 到 2 ms 之内

总结

可以看出将 Jetpack Compose 版的灵动岛迁移到 Compose Multiplatform 的成本是非常低的,最耗时的部分可能是配环境的部分,两者的 API 基本上是一致的,因此代码可以无缝复用

Compose 跨平台补全了 Kotlin 跨平台只支持共享逻辑不支持共享 UI 的短板,降低了 Kotlin 跨平台的开发成本,总得来说,未来可期,希望 Jetbrains 能早日推出正式版

示例代码

本文所有代码可见:github.com/RicardoJian…

参考资料

Compose Multiplatform on iOS by: Sebastian Aigner and Nikita Lipsky

Guess you like

Origin juejin.im/post/7235547967113035813