
안녕하세요 !
이번에는 TCA MultiStore 라는 주제로 포스팅해보겠습니다
MultiStore 패턴의 개념, 구현 방법, 그리고 실제 사용 사례를 통해 이 패턴이 어떻게 앱의 구조를 개선하고 유지보수성을 높이는지 알아보도록해요~~~
MultiStore 패턴은 TCA에서 여러 개의 독립적인 스토어를 사용하여 앱의 상태를 관리하는 방식이고 이 패턴은 큰 규모의 앱에서 특히 유용하며, 코드의 모듈화와 재사용성을 높이는 데 도움이 됩니다
- 모듈화: 각 기능을 독립적인 스토어로 분리하여 관리할 수 있음
- 성능 향상: 필요한 부분만 업데이트되므로 전체 앱의 성능이 개선
- 테스트 용이성: 각 스토어를 독립적으로 테스트할 수 있음
- 유지보수성: 코드의 구조가 명확해져 유지보수가 쉬움
예시 - 사용자 프로필과 설정을 관리하는 두 개의 스토어를 만들어 볼게요
struct ProfileState: Equatable {
var name: String = ""
var age: Int = 0
}
enum ProfileAction {
case setName(String)
case setAge(Int)
}
let profileReducer = Reducer<ProfileState, ProfileAction, Void> { state, action, _ in
switch action {
case let .setName(name):
state.name = name
return .none
case let .setAge(age):
state.age = age
return .none
}
}
struct SettingsState: Equatable {
var isDarkMode: Bool = false
var notificationsEnabled: Bool = true
}
enum SettingsAction {
case toggleDarkMode
case toggleNotifications
}
let settingsReducer = Reducer<SettingsState, SettingsAction, Void> { state, action, _ in
switch action {
case .toggleDarkMode:
state.isDarkMode.toggle()
return .none
case .toggleNotifications:
state.notificationsEnabled.toggle()
return .none
}
}
이제 이 두 스토어를 결합하여 앱의 전체 상태를 관리하는 AppState를 만들어 보겠습니다
struct AppState: Equatable {
var profile: ProfileState
var settings: SettingsState
}
enum AppAction {
case profile(ProfileAction)
case settings(SettingsAction)
}
let appReducer = Reducer<AppState, AppAction, Void>.combine(
profileReducer.pullback(
state: \.profile,
action: /AppAction.profile,
environment: { _ in () }
),
settingsReducer.pullback(
state: \.settings,
action: /AppAction.settings,
environment: { _ in () }
)
)
이렇게 구성된 MultiStore 패턴을 사용하면, 각 기능별로 독립적인 상태 관리가 가능해집니다
예를 들어, 프로필 화면에서는 ProfileState만 사용하고, 설정 화면에서는 SettingsState만 사용할 수 있습니다
실제 뷰에서 사용하는 방법
struct ProfileView: View {
let store: Store<ProfileState, ProfileAction>
var body: some View {
WithViewStore(self.store) { viewStore in
VStack {
TextField("Name", text: viewStore.binding(
get: \.name,
send: ProfileAction.setName
))
Stepper("Age: \(viewStore.age)", value: viewStore.binding(
get: \.age,
send: ProfileAction.setAge
))
}
}
}
}
struct SettingsView: View {
let store: Store<SettingsState, SettingsAction>
var body: some View {
WithViewStore(self.store) { viewStore in
Form {
Toggle("Dark Mode", isOn: viewStore.binding(
get: \.isDarkMode,
send: SettingsAction.toggleDarkMode
))
Toggle("Notifications", isOn: viewStore.binding(
get: \.notificationsEnabled,
send: SettingsAction.toggleNotifications
))
}
}
}
}
다음 포스팅에서는 다른 예시들을 보면서 좀 더 자세히 알아보겠습니다
이상으로 포스팅 마무리 하겠습니다.
.
.
.
감사합니다.