前言

Apple 推出了由 Swift 语言的宏功用支撑的新调查结构。新的调查结构与 Swift 并发功用结合运用,允许咱们代替 Apple 公司看起来现已过期的 Combine 结构。下面将介绍如何运用调查结构来处理运用程序中的数据流。

运用 @Observable

RevenueCat 简化了施行运用内购买、办理客户和扩展运用事务的过程。无论你是第一次添加运用内购买和订阅,仍是现已有数百万付费用户,你都能够在几分钟内开始运用 RevenueCat。看看为什么有超越 30,000 个运用程序运用 RevenueCat 来支撑其运用事务。你能够检查他们的文档以了解更多信息。

运用新的调查结构非常容易。你只需求运用 @Observable 宏标记你的类。

@Observable final class Store<State, Action> {
    typealias Reduce = (State, Action) -> State
    private(set) var state: State
    private let reduce: Reduce
    init(initialState state: State, reduce: @escaping Reduce) {
        self.state = state
        self.reduce = reduce
    }
    func send(_ action: Action) {
        state = reduce(state, action)
    }
}

调查 Store

正如你在上面的示例中所看到的,咱们运用 @Observable 宏来注释咱们的 Store 类型。之后,咱们能够调查 Store 类型中的任何变量。咱们在 Store 类型中只有一个变量,用于定义存储的状况。另一个字段是一个永不更改的 let 常量。

withObservationTracking {
    render(store.state)
} onChange: {
    print("State changed")
}

调用闭包

要调查 Store 类型的实例,咱们需求运用 withObservationTracking 函数调用两个闭包。在第一个闭包中,咱们能够访问可调查类型的所有必要特点。调查结构仅在触摸到的调查类型的任何特点更改后才调用第二个闭包。

func startObservation() {
    withObservationTracking {
        render(store.state)
    } onChange: {
        Task { startObservation() }
    }
}

调查结构仅运转一次 onChange,这意味着你应该递归调用它以不断调查更改。你还应该留意的另一件事是 onChange 闭包在实际更改运用之前运转。这就是为什么咱们通过发动新任务来推迟 onChange 操作的原因。

SwiftUI 主动盯梢

在 SwiftUI 中,你不需求运用 withObservationTracking 函数来调查更改。SwiftUI 主动盯梢视图正文中运用的任何可调查类型特点的更改。

struct ProductsView: View {
    let store: Store<AppState, AppAction>
    var body: some View {
        List(store.state.products, id: .self) { product in
            Text(product)
        }
        .onAppear {
            store.send(.fetch)
        }
    }
}

正如你在上面的示例中所看到的,咱们不运用任何特点包装器来调查存储。SwiftUI 主动履行此操作。只要存储的状况特点更改,SwiftUI 就会更新视图。咱们不需求 @ObservedObject 特点包装器来盯梢可调查类型中的更改,但咱们依然需求 @StateObject 代替项以在 SwiftUI 生命周期中存活。

运用 @State

Apple 简化了咱们应该在新的调查结构中运用的特点包装器集。现在,咱们能够运用 @State 而不是 @StateObject 特点包装器。@State 特点包装器现在适用于简单的值类型和任何可调查类型。

struct ContentView: View {
    @State private var store = Store<AppState, AppAction>(
        initialState: .init(),
        reduce: reduce
    )
    var body: some View {
        ProductsView(store: store)
    }
}

运用 @Environment

相同的办法适用于 SwiftUI 结构的环境功用。现在不再需求 @EnvironmentObject 特点包装器。你现在能够运用 @Environment 特点包装器和具有可调查类型的环境视图修改器。

struct ContentView: View {
    @State private var store = Store<AppState, AppAction>(
        initialState: .init(),
        reduce: reduce
    )
    var body: some View {
        ProductsView()
            .environment(store)
    }
}
struct ProductsView: View {
    @Environment(Store<AppState, AppAction>.self) var store
    var body: some View {
        List(store.state.products, id: .self) { product in
            Text(product)
        }
        .onAppear {
            store.send(.fetch)
        }
    }
}

运用 @Bindable

你可能会想知道的最终一件事是如何从可调查类型中派生绑定。SwiftUI 为此引入了 @Bindable 特点包装器,只能与可调查类型一同运用。

@Observable final class AuthViewModel {
    var username = ""
    var password = ""
    var isAuthorized = false
    func authorize() {
        isAuthorized.toggle()
    }
}
struct AuthView: View {
    @Bindable var viewModel: AuthViewModel
    var body: some View {
        VStack {
            if !viewModel.isAuthorized {
                TextField("username", text: $viewModel.username)
                SecureField("password", text: $viewModel.password)
                Button("authorize") {
                    viewModel.authorize()
                }
            } else {
                Text("Hello, (viewModel.username)")
            }
        }
    }
}

你能够运用 @Bindable 特点包装器轻松地从任何可调查类型的特点创立绑定。有时,你可能需求内联 @Bindable 到视图正文中以创立绑定。

struct InlineAuthView: View {
    @Environment(AuthViewModel.self) var viewModel
    var body: some View {
        @Bindable var viewModel = viewModel
        VStack {
            if !viewModel.isAuthorized {
                TextField("username", text: $viewModel.username)
                SecureField("password", text: $viewModel.password)
                Button("authorize") {
                    viewModel.authorize()
                }
            } else {
                Text("Hello, (viewModel.username)")
            }
        }
    }
}

总结

这篇文章介绍了苹果引入的全新调查结构,该结构使用 Swift 语言的宏功用。新的调查结构结合了 Swift 并发功用,使咱们能够代替苹果看似现已过期的 Combine 结构。

总的来说,新的调查结构使 SwiftUI 中的数据流办理更加轻松和高效。