ObservableConverter

来自 LickabilityObservableConverter 是一个基础插件,旨在帮助你将使用 ObservableObject 及其相关属性包装器和视图修饰符的 SwiftUI 代码,转换为使用 Apple 新推出的 @Observable 宏,该宏在 WWDC 2023 上发布,适用于 iOS 17、macOS 14、watchOS 10 和 tvOS 17。

A screenshot of the menu you see when right-clicking a target, with the ObservableConverter plugin option highlighted

安装

ObservableConverter 是一个 Swift Package Manager 命令插件,因此只能通过 Xcode 15 beta 7 及更高版本上的 SPM 进行安装。

在 Xcode 中,转到 “File(文件)” 并选择 “Add Package Dependencies(添加包依赖项)”。将此仓库的 URL 粘贴到搜索栏中并选择它。当询问要将哪个框架嵌入到你的目标中时,选择 “None(无)”,因为此工具纯粹用于代码转换目的,不应作为你的应用程序的一部分构建。

使用方法

作为一个命令插件,一旦安装了 ObservableConverter,使用起来非常简单,只需在 Xcode 项目导航器中右键单击要转换的目标,然后在菜单中选择 “Convert Target to Use @Observable(将目标转换为使用 @Observable)” 选项即可!

此仓库还包含一个使用 ObservableObject 的示例项目,以便你可以亲自查看转换过程。打开 Examples 文件夹中的 xcodeproj,然后右键单击目标以查看它如何将现有代码转换为使用 @Observable

以下是一些示例代码在转换之前的样子

final class ViewModelTest: ObservableObject {
    @Published var publishedProperty: String?
}

struct ContentView: View {
    @StateObject private var viewModel = ViewModelTest()
    @EnvironmentObject private var environmentModel: ViewModelTest
    
    var body: some View {
        VStack {
            ChildView(model: viewModel)
                .environmentObject(environmentModel)
        }
        .padding()
    }
}

struct ChildView: View {
    @ObservedObject var model: ViewModelTest
    
    var body: some View {
        Text(model.publishedProperty ?? "no value set")
            .onTapGesture {
                model.publishedProperty = "model value changed"
            }
    }
}

这是转换之后的样子 🎉

@Observable
final class ViewModelTest {
    var publishedProperty: String?
}

struct ContentView: View {
    @State private var viewModel = ViewModelTest()
    @Environment(ViewModelTest.self) private var environmentModel 
    
    var body: some View {
        VStack {
            ChildView(model: viewModel)
                .environment(environmentModel)
        }
        .padding()
    }
}

struct ChildView: View {
    var model: ViewModelTest
    
    var body: some View {
        Text(model.publishedProperty ?? "no value set")
            .onTapGesture {
                model.publishedProperty = "model value changed"
            }
    }
}

注意事项

虽然此工具可以处理基本的转换实例,但它仍然处于 beta 阶段,需要一些额外的功能。请在使用时进行源代码控制,以便你可以还原你不喜欢的任何更改。

未来可以处理的更高级用例

需要更多帮助?

需要更多帮助来让你的应用程序为 iOS 17+ 做好准备吗?这就是我们在 Lickability 所做的事情 – 联系我们,看看我们如何能为您提供服务!

Lickability