使用 Observation 框架 App 管理全局状态
了解如何使用最新的 Observation 框架,简化通过 AppState 管理 App 状态的流程。
在之前的这篇文章中,我们详细讲解了如何使用 EnvironmentObject 创建 AppState,来管理全局状态:
从 iOS 17 开始,Swift 推出了全新的 Observation 框架。通过 Observation 框架创建 AppState,可以更高效地管理全局状态,让代码更清晰简洁,进一步提升开发体验和可读性。
使用 Observation 创建 AppState
Observation 框架提供了一种新的方式来观察和响应状态变化。
定义 AppState 类
在使用 Observation 框架时,你只需要让你的类遵循 Observable 协议,而不需要对属性进行额外的标记。
import SwiftUI
import Observation
@Observable
class AppState {
var isAuthenticated: Bool = false
func logIn() {
// 这里可以添加实际的登录逻辑
self.isAuthenticated = true
}
func logOut() {
// 这里可以添加实际的登出逻辑
self.isAuthenticated = false
}
}
在 App 文件中初始化 AppState 实例
在应用的入口点(通常是 App 的主体部分),创建 AppState 的实例,并使用 .environment 方法将它注入到环境中。
和 EnvironmentObject 不同,我们无需使用 @StateObject
属性包装器,使用基本的@State
即可。
@main
struct MyApp: App {
@State var appState = AppState()
var body: some Scene {
WindowGroup {
ContentView()
.environment(appState)
}
}
}
注意是 var appState = AppState()
,而不是 var appState: AppState
,前者创建了一个 AppState 类的实例,而后者没有。
在视图中访问 AppState
在 SwiftUI 视图中,可以通过 @Environment 属性包装器来获取 AppState 的实例。当状态更新时,SwiftUI 组件会自动更新 UI。
struct ContentView: View {
@Environment(AppState.self) private var appState
var body: some View {
VStack {
if appState.isAuthenticated {
Text("用户已认证")
Button("登出") {
appState.logOut()
}
} else {
Text("用户未认证")
Button("登录") {
appState.logIn()
}
}
}
}
}
这样,我们就实现了一个简单的登录逻辑,将这些逻辑放在 AppState 中,可以让任何视图通过简单地调用 appState.logIn()
来实现用户登录,而无需关心登录过程的具体细节。这种方法也便于在后续需要修改登录逻辑时,只需在 AppState 中修改,无需触及任何使用了登录功能的视图。
在双向绑定组件中使用 AppState
要在支持双向绑定的 SwiftUI 组件中使用 AppState,可以使用 @Bindable 属性包装器。
例如,将 appState 绑定到 Picker 组件上:
struct HomeView: View
@Environment(AppState.self) private var appState
var body: some View {
NavigationStack {
HomeContentView(
)
.safeAreaInset(edge: .top, spacing: 0) {
// 在这里使用 @Bindable
@Bindable var appState = appState
Picker("记录类型", selection: $appState.selected) {
ForEach([Category.all, .income, .expense]) { category in
Text(category.displayName)
.tag(category)
}
}
.pickerStyle(.segmented)
}
}
}
}