升级指南
本页面包含 Skip 主要版本之间的升级指南。如果你正在启动一个新项目,这些指南不适用于你。请参阅入门指南。
Skip 0.x 到 Skip 1.0 迁移
Section titled “Skip 0.x 到 Skip 1.0 迁移”Skip 和 Swift Package Manager 都使用语义化版本 ↗。虽然语义化版本有许多优点 ↗,但这也意味着从 Skip 0.x 升级到 Skip 1.x 被视为潜在的“破坏性变更”,因此需要手动升级步骤。要将你的 Skip 0.x 库或应用迁移到 Skip 1.x,请执行以下操作:
-
在你的
Package.swift文件中,将对以下 Skip 包的依赖从from: 0.x.y更新为from: 1.0.0:skipskip-unitskip-libskip-foundationskip-modelskip-ui
例如,以下是我们的
HelloSkip示例应用更新后的Package.swift:import PackageDescription...let package = Package(name: "skipapp-hello",...dependencies: [.package(url: "https://github.com/skiptools/skip.git", from: "1.0.0"),.package(url: "https://github.com/skiptools/skip-ui.git", from: "1.0.0")],...) -
在 Xcode 中打开你的项目并运行
File → Packages → Update to Latest Package Versions -
删除项目文件夹中的
.build/目录和Package.resolved文件。
如果遇到任何问题,请联系支持!
Skip 1.0 到 Skip 1.1 迁移
Section titled “Skip 1.0 到 Skip 1.1 迁移”Android/settings.gradle.kts 的必要更改
Section titled “Android/settings.gradle.kts 的必要更改”Android/settings.gradle.kts 中的 commandLine 调用需要调用 xcrun swift build …,而不是之前的 swift build。完整示例可以参考 skip-hello 应用的构建文件:https://source.skip.dev/skipapp-hello/blob/main/Android/settings.gradle.kts ↗。
// 这个 gradle 项目是常规 Skip 应用项目的一部分。// 它调用了共享的 build skip 插件逻辑,该逻辑作为 skip-unit buildSrc 的一部分包含// 从 Android Studio 构建时,它使用 BUILT_PRODUCTS_DIR 文件夹与 Xcode 共享相同的构建输出,否则使用 SwiftPM 的 .build/ 文件夹pluginManagement { // BUILT_PRODUCTS_DIR 的本地覆盖 if (System.getenv("BUILT_PRODUCTS_DIR") == null) { //System.setProperty("BUILT_PRODUCTS_DIR", "${System.getProperty("user.home")}/Library/Developer/Xcode/DerivedData/MySkipProject-aqywrhrzhkbvfseiqgxuufbdwdft/Build/Products/Debug-iphonesimulator") }
// 插件源码作为 SkipUnit 转译的一部分链接 val skipOutput = System.getenv("BUILT_PRODUCTS_DIR") ?: System.getProperty("BUILT_PRODUCTS_DIR")
val outputExt = if (skipOutput != null) ".output" else "" // Xcode 将输出保存在 package-name.output 中;SPM 没有后缀 val skipOutputs: File = if (skipOutput != null) { // BUILT_PRODUCTS_DIR 在从 Xcode 构建时设置,此时我们将使用 Xcode 的 DerivedData 插件输出 file(skipOutput).resolve("../../../SourcePackages/plugins/") } else { exec { // 从 SwiftPM 模块生成转译的 Kotlin 并生成 Gradle 项目 commandLine("sh", "-c", "xcrun swift build --triple arm64-apple-ios --sdk $(xcrun --sdk iphoneos --show-sdk-path)") workingDir = file("..") } // SPM 输出文件夹是父级 Package.swift 的同级目录 rootDir.resolve("../.build/plugins/outputs/") }
// 加载 Skip 插件(skip-unit 项目的一部分),它负责配置 Android 项目 // 因为这个路径是一个符号链接,我们需要使用规范路径,否则 gradle 会将其误解为不同的构建源 var pluginSource = skipOutputs.resolve("skip-unit${outputExt}/SkipUnit/skipstone/buildSrc/").canonicalFile if (!pluginSource.isDirectory) { // 检查新 SwiftPM6 插件的 "destination" 文件夹以进行命令行构建 pluginSource = skipOutputs.resolve("skip-unit${outputExt}/SkipUnit/destination/skipstone/buildSrc/").canonicalFile }
if (!pluginSource.isDirectory) { throw GradleException("Missing expected Skip output folder: ${pluginSource}. Run `swift build` in the root folder to create, or specify Xcode environment BUILT_PRODUCTS_DIR.") } includeBuild(pluginSource.path) { name = "skip-plugins" }}
plugins { id("skip-plugin") apply true}Kotlin 1.x 到 Kotlin 2 迁移
Section titled “Kotlin 1.x 到 Kotlin 2 迁移”Kotlin 2 引入了许多对 Kotlin 语言的改进,并将 Compose 编译器集成到了 Kotlin 编译器本身1。Skip 0.9.2 采用 Kotlin 2 作为目标语言,这涉及对 Skip 创建的 Gradle 项目的一些更改2。在内部,这涉及更改 Skip 添加到 Android Gradle 项目的一些依赖。
这些更改对于 Skip 框架项目来说大部分是透明的。但在 Skip 0.9.2 之前创建的 Skip 应用项目需要进行一些更改才能与新的 Compose 编译器配合使用。
要升级 Skip 应用项目,在任何文本编辑器(如 Xcode、Android Studio 或 TextEdit)中打开 Android/app/build.gradle.kts 文件,并进行以下更改:
- 在
plugins { }块中添加alias(libs.plugins.kotlin.compose) - 从
composeOptions { }块中移除kotlinCompilerExtensionVersion = libs.versions.kotlin.compose.compiler.extension.get()
skip-build-plugin 包含在所有使用 skip init 创建的 Skip 应用项目中,如果检测到你的项目需要更新,它会提供有用的错误消息:
{: style=“width: 100%;”}
{: style=“text-align: center; margin: auto;“}
Android/app/build.gradle.kts 的必要更改
Section titled “Android/app/build.gradle.kts 的必要更改”以下是对 Android/app/build.gradle.kts 所需更改的简要对比。完整示例可以参考 skip-hello 应用的构建文件:https://source.skip.dev/skipapp-hello/blob/main/Android/app/build.gradle.kts ↗。
更改前:
plugins { alias(libs.plugins.kotlin.android) alias(libs.plugins.android.application) id("skip-build-plugin")}
android { namespace = group as String compileSdk = libs.versions.android.sdk.compile.get().toInt() compileOptions { sourceCompatibility = JavaVersion.toVersion(libs.versions.jvm.get()) targetCompatibility = JavaVersion.toVersion(libs.versions.jvm.get()) }
defaultConfig { minSdk = libs.versions.android.sdk.min.get().toInt() targetSdk = libs.versions.android.sdk.compile.get().toInt() }
composeOptions { kotlinCompilerExtensionVersion = libs.versions.kotlin.compose.compiler.extension.get() }}更改后:
plugins { alias(libs.plugins.kotlin.android) alias(libs.plugins.kotlin.compose) // 添加此行 alias(libs.plugins.android.application) id("skip-build-plugin")}
android { namespace = group as String compileSdk = libs.versions.android.sdk.compile.get().toInt()
compileOptions { sourceCompatibility = JavaVersion.toVersion(libs.versions.jvm.get()) targetCompatibility = JavaVersion.toVersion(libs.versions.jvm.get()) }
kotlinOptions { jvmTarget = libs.versions.jvm.get().toString() // 添加此行 }
defaultConfig { minSdk = libs.versions.android.sdk.min.get().toInt() targetSdk = libs.versions.android.sdk.compile.get().toInt() }
composeOptions { // kotlinCompilerExtensionVersion = libs.versions.kotlin.compose.compiler.extension.get() // 移除此行 }}错误:检测到任务 ‘compileDebugJavaWithJavac’ (17) 和 ‘compileDebugKotlin’ (22) 的 JVM 目标兼容性不一致。
Section titled “错误:检测到任务 ‘compileDebugJavaWithJavac’ (17) 和 ‘compileDebugKotlin’ (22) 的 JVM 目标兼容性不一致。”整个 Gradle 项目必须使用相同的 JVM 目标,包括你自己的应用以及所有 Skip 依赖。之前这是通过 compileOptions 块的 sourceCompatibility 和 targetCompatibility 属性自动完成的,但现在还需要使用 jvmTarget 属性将其添加到 kotlinOptions 块中。按如下方式编辑你的 build.gradle.kts 文件:
android { compileOptions { sourceCompatibility = JavaVersion.toVersion(libs.versions.jvm.get()) targetCompatibility = JavaVersion.toVersion(libs.versions.jvm.get()) }
kotlinOptions { jvmTarget = libs.versions.jvm.get().toString() // 添加此行 }}错误:Exception during IR lowering
Section titled “错误:Exception during IR lowering”当 Compose 编译器插件未添加到应用的 Android/app/build.gradle.kts 文件时,会出现此错误。确保你已按照本迁移指南中的说明修复此错误。
此错误的简要表示如下:
e: org.jetbrains.kotlin.backend.common.BackendException: Backend Internal error: Exception during IR lowering> Task :app:compileDebugKotlin FAILEDFile being compiled: /opt/src/github/skiptools/skipapp-hello/Android/app/src/main/kotlin/hello/skip/Main.ktThe root cause java.lang.RuntimeException was thrown at: org.jetbrains.kotlin.backend.jvm.codegen.FunctionCodegen.generate(FunctionCodegen.kt:50) at org.jetbrains.kotlin.backend.common.CodegenUtil.reportBackendException(CodegenUtil.kt:253) at org.jetbrains.kotlin.backend.common.CodegenUtil.reportBackendException$default(CodegenUtil.kt:236) at org.jetbrains.kotlin.backend.common.phaser.PerformByIrFilePhase.invokeSequential(performByIrFile.kt:65) …Caused by: java.lang.RuntimeException: Exception while generating code for:FUN LOCAL_FUNCTION_FOR_LAMBDA name:PresentationRootView$lambda$1 visibility:private modality:FINAL <> (ctx:skip.ui.ComposeContext) returnType:kotlin.Unit? VALUE_PARAMETER name:ctx index:0 type:skip.ui.ComposeContext BLOCK_BODY VAR name:contentContext type:skip.ui.ComposeContext [val]Footnotes
Section titled “Footnotes”-
Jetpack Compose 编译器迁移到 Kotlin 仓库:https://android-developers.googleblog.com/2024/04/jetpack-compose-compiler-moving-to-kotlin-repository.html ↗ ↩
-
迁移 Jetpack Compose 项目:https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-compiler.html#migrating-a-jetpack-compose-project ↗ ↩