📦 Unidirectional Data Flow State Management Library
Unidirectional data flow state management library.
Unidirectional data flow state management library.
Swift Package Manager is a tool for managing the distribution of Swift code. It’s integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies.
To integrate Store
into your Xcode project using Swift Package Manager, add it to the dependencies value of your Package.swift:
dependencies: [
.package(url: "https://github.com/GSM-MSG/Store.git", .upToNextMajor(from: "1.0.0"))
]
If you prefer not to use either of the aforementioned dependency managers, you can integrate MSGLayout into your project manually.
import Combine
import Store
import UIKit
// MARK: - Store
final class SampleStore: Store {
struct State: Equatable {
var count: Int = 0
}
enum Action {
case plusButtonDidTap
case minusButtonDidTap
}
enum Mutation {
case updateCount(Int)
}
var stateSubject: CurrentValueSubject<State, Never>
var initialState: State
var subscription: Set<AnyCancellable> = .init()
init(initialState: State) {
self.initialState = initialState
self.stateSubject = CurrentValueSubject(initialState)
}
func mutate(state: State, action: Action) -> SideEffect<Mutation, Never> {
switch action {
case .plusButtonDidTap:
return .tryAsync { [count = state.count] in
try await Task.sleep(for: .milliseconds(500))
return .updateCount(count + 1)
}
.catchToNever()
case .minusButtonDidTap:
return .just(.updateCount(state.count - 1))
default :
return .none
}
return .none
}
func reduce(state: State, mutate: Mutation) -> State {
var newState = state
switch mutate {
case let .updateCount(count):
newState.count = count
}
return newState
}
}
// MARK: - ViewController
final class SampleViewController: UIViewController {
let store: SampleStore
var subscription: Set<AnyCancellable> = .init()
init() {
self.store = .init(initialState: .init())
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private let countLabel: UILabel = {...}()
private let plusButton: UIButton = {...}()
private let minusButton: UIButton = {...}()
override func viewDidLoad() {
super.viewDidLoad()
...
plusButton.addAction(UIAction(handler: { [weak self] _ in
self?.store.send(.plusButtonDidTap)
}), for: .touchUpInside)
minusButton.addAction(UIAction(handler: { [weak self] _ in
self?.store.send(.minusButtonDidTap)
}), for: .touchUpInside)
store.state.map(\.count)
.map(String.init)
.assign(to: \.text, on: countLabel)
.store(in: &subscription)
}
}