### SwiftUI Counter Example with Store and Reducer Source: https://context7.com/mecid/swift-unidirectional-flow/llms.txt Demonstrates a basic counter application using the Store for state management and a Reducer for handling state mutations. It showcases action dispatching and state observation within a SwiftUI View. Dependencies include UnidirectionalFlow and SwiftUI. ```swift import UnidirectionalFlow import SwiftUI // Define your state struct CounterState: Equatable { var count: Int = 0 var isEven: Bool { count % 2 == 0 } } // Define your actions enum CounterAction: Equatable { case increment case decrement case reset } // Create a reducer struct CounterReducer: Reducer { func reduce(oldState: CounterState, with action: CounterAction) -> CounterState { var state = oldState switch action { case .increment: state.count += 1 case .decrement: state.count -= 1 case .reset: state.count = 0 } return state } } // Initialize and use the store @MainActor struct CounterView: View { @State private var store = Store( initialState: CounterState(), reducer: CounterReducer(), middlewares: [] ) var body: some View { VStack { Text("Count: \(store.count)") Text(store.isEven ? "Even" : "Odd") HStack { Button("Increment") { Task { await store.send(.increment) } } Button("Decrement") { Task { await store.send(.decrement) } } Button("Reset") { Task { await store.send(.reset) } } } } } } ``` -------------------------------- ### Todo List Reducer Implementation in Swift Source: https://context7.com/mecid/swift-unidirectional-flow/llms.txt Implements a Reducer for managing a list of todos, including actions for adding, toggling, deleting, and filtering todos. This example demonstrates handling complex state transformations and introduces the concept of combined reducers. Dependencies include UnidirectionalFlow. ```swift import UnidirectionalFlow struct TodoState: Equatable { var items: [Todo] = [] var filter: Filter = .all } struct Todo: Equatable, Identifiable { let id: UUID var title: String var completed: Bool } enum Filter { case all, active, completed } enum TodoAction: Equatable { case addTodo(title: String) case toggleTodo(id: UUID) case deleteTodo(id: UUID) case setFilter(Filter) case clearCompleted } struct TodoReducer: Reducer { func reduce(oldState: TodoState, with action: TodoAction) -> TodoState { var state = oldState switch action { case let .addTodo(title): let todo = Todo(id: UUID(), title: title, completed: false) state.items.append(todo) case let .toggleTodo(id): if let index = state.items.firstIndex(where: { $0.id == id }) { state.items[index].completed.toggle() } case let .deleteTodo(id): state.items.removeAll { $0.id == id } case let .setFilter(filter): state.filter = filter case .clearCompleted: state.items.removeAll { $0.completed } } return state } } // Usage with combined reducers let combinedReducer = CombinedReducer( reducers: TodoReducer(), IdentityReducer() ) ``` -------------------------------- ### SwiftUI View with Unidirectional Flow Integration Source: https://github.com/mecid/swift-unidirectional-flow/blob/main/README.md Demonstrates integrating the unidirectional data flow pattern into a SwiftUI view. `SearchContainerView` manages its state using a `Store`, binds UI elements to the state, and dispatches actions in response to user interactions and lifecycle events. ```swift typealias SearchStore = Store struct SearchContainerView: View { @State private var store = SearchStore( initialState: .init(), reducer: SearchReducer(), middlewares: [SearchMiddleware(dependencies: .production)] ) @State private var query = "" var body: some View { List(store.repos) { repo in VStack(alignment: .leading) { Text(verbatim: repo.name) .font(.headline) if let description = repo.description { Text(verbatim: description) } } } .redacted(reason: store.isLoading ? .placeholder : []) .searchable(text: $query) .task(id: query) { await store.send(.search(query: query)) } .navigationTitle("Github Search") } } ``` -------------------------------- ### Swift Middleware for Side Effects (GitHub API) Source: https://github.com/mecid/swift-unidirectional-flow/blob/main/README.md Implements middleware for handling asynchronous side effects, such as network requests. The `SearchMiddleware` actor demonstrates fetching repository search results from the GitHub API, showing dependency injection for the network call and handling task cancellation. ```swift actor SearchMiddleware: Middleware { struct Dependencies { var search: (String) async throws -> SearchResponse static var production: Dependencies { .init { query in guard var urlComponents = URLComponents(string: "https://api.github.com/search/repositories") else { return .init(items: []) } urlComponents.queryItems = [.init(name: "q", value: query)] guard let url = urlComponents.url else { return .init(items: []) } let (data, _) = try await URLSession.shared.data(from: url) return try JSONDecoder().decode(SearchResponse.self, from: data) } } } let dependencies: Dependencies init(dependencies: Dependencies) { self.dependencies = dependencies } func process(state: SearchState, with action: SearchAction) async -> SearchAction? { switch action { case let .search(query): let results = try? await dependencies.search(query) guard !Task.isCancelled else { return .setResults(repos: state.repos) } return .setResults(repos: results?.items ?? []) default: return nil } } } ``` -------------------------------- ### Swift: Type Transformation and Reducer Composition using Prism Source: https://context7.com/mecid/swift-unidirectional-flow/llms.txt This Swift code defines parent and child states and actions, along with their respective reducers. It then uses Prism to lift child reducers to operate on the parent state and action types, demonstrating composition of reducers for a combined application reducer and store. ```swift import UnidirectionalFlow // Parent state and actions struct AppState: Equatable { var user: UserState var settings: SettingsState } enum AppAction: Equatable { case user(UserAction) case settings(SettingsAction) } // Child state and actions struct UserState: Equatable { var name: String var isLoggedIn: Bool } enum UserAction: Equatable { case login(name: String) case logout } struct UserReducer: Reducer { func reduce(oldState: UserState, with action: UserAction) -> UserState { var state = oldState switch action { case let .login(name): state.name = name state.isLoggedIn = true case .logout: state.name = "" state.isLoggedIn = false } return state } } // Create a prism to lift the UserReducer to work with AppState/AppAction let userPrism = Prism( embed: { AppAction.user($0) }, extract: { action in guard case let .user(userAction) = action else { return nil } return userAction } ) // Lift the reducer to work with parent types let liftedUserReducer = UserReducer().lifted( keyPath: \AppState.user, prism: userPrism ) // Settings reducer struct SettingsState: Equatable { var darkMode: Bool = false var notifications: Bool = true } enum SettingsAction: Equatable { case toggleDarkMode case toggleNotifications } struct SettingsReducer: Reducer { func reduce(oldState: SettingsState, with action: SettingsAction) -> SettingsState { var state = oldState switch action { case .toggleDarkMode: state.darkMode.toggle() case .toggleNotifications: state.notifications.toggle() } return state } } let settingsPrism = Prism( embed: { AppAction.settings($0) }, extract: { action in guard case let .settings(settingsAction) = action else { return nil } return settingsAction } ) let liftedSettingsReducer = SettingsReducer().lifted( keyPath: \AppState.settings, prism: settingsPrism ) // Combine all reducers let appReducer = CombinedReducer( reducers: liftedUserReducer, liftedSettingsReducer ) // Create the store let appStore = Store( initialState: AppState( user: UserState(name: "", isLoggedIn: false), settings: SettingsState() ), reducer: appReducer, middlewares: [] ) ``` -------------------------------- ### Swift Unidirectional Data Flow Components Source: https://github.com/mecid/swift-unidirectional-flow/blob/main/README.md Defines the core components of the unidirectional data flow pattern: state, actions, and reducers. The `SearchState` holds the application's state, `SearchAction` represents events that can modify the state, and `SearchReducer` is responsible for updating the state based on actions. ```swift struct SearchState: Equatable { var repos: [Repo] = [] var isLoading = false } enum SearchAction: Equatable { case search(query: String) case setResults(repos: [Repo]) } struct SearchReducer: Reducer { func reduce(oldState: SearchState, with action: SearchAction) -> SearchState { var state = oldState switch action { case .search: state.isLoading = true case let .setResults(repos): state.repos = repos state.isLoading = false } return state } } ``` -------------------------------- ### Swift Middleware for Async API Calls in Unidirectional Flow Source: https://context7.com/mecid/swift-unidirectional-flow/llms.txt This Swift code defines an actor-based middleware to handle asynchronous side effects, specifically fetching repository data from the GitHub API. It intercepts a 'search' action, makes an asynchronous API call using URLSession, and returns either a 'setResults' action with the fetched repositories or a 'setError' action if an error occurs. Dependencies for the API call are injectable, allowing for mock implementations during testing. The middleware is designed to work with the UnidirectionalFlow framework and handles cancellation gracefully. ```swift import UnidirectionalFlow import Foundation struct SearchState: Equatable { var repos: [Repo] = [] var isLoading = false var error: String? } struct Repo: Identifiable, Equatable, Decodable { let id: Int let name: String let description: String? } struct SearchResponse: Decodable { let items: [Repo] } enum SearchAction: Equatable { case search(query: String) case setResults(repos: [Repo]) case setError(message: String) } // Actor-based middleware for API calls actor SearchMiddleware: Middleware { struct Dependencies { var search: (String) async throws -> SearchResponse static var production: Dependencies { .init { query in guard var urlComponents = URLComponents(string: "https://api.github.com/search/repositories") else { return .init(items: []) } urlComponents.queryItems = [.init(name: "q", value: query)] guard let url = urlComponents.url else { return .init(items: []) } let (data, _) = try await URLSession.shared.data(from: url) return try JSONDecoder().decode(SearchResponse.self, from: data) } } } let dependencies: Dependencies init(dependencies: Dependencies) { self.dependencies = dependencies } func process(state: SearchState, with action: SearchAction) async -> SearchAction? { switch action { case let .search(query): guard !query.isEmpty else { return .setResults(repos: []) } do { let results = try await dependencies.search(query) guard !Task.isCancelled else { return .setResults(repos: state.repos) } return .setResults(repos: results.items) } catch { return .setError(message: error.localizedDescription) } default: return nil } } } struct SearchReducer: Reducer { func reduce(oldState: SearchState, with action: SearchAction) -> SearchState { var state = oldState switch action { case .search: state.isLoading = true state.error = nil case let .setResults(repos): state.repos = repos state.isLoading = false case let .setError(message): state.error = message state.isLoading = false } return state } } // Complete integration example @MainActor struct SearchView: View { @State private var store = Store( initialState: SearchState(), reducer: SearchReducer(), middlewares: [SearchMiddleware(dependencies: .production)] ) @State private var query = "" var body: some View { List(store.repos) { repo in VStack(alignment: .leading) { Text(repo.name) .font(.headline) if let description = repo.description { Text(description) .font(.caption) } } } .overlay { if let error = store.error { Text("Error: \(error)") .foregroundColor(.red) } } .redacted(reason: store.isLoading ? .placeholder : []) .searchable(text: $query) .task(id: query) { await store.send(.search(query: query)) } } } ``` -------------------------------- ### SwiftUI: Collection View with Unidirectional State Flow Source: https://context7.com/mecid/swift-unidirectional-flow/llms.txt Demonstrates a SwiftUI view that interacts with a collection of items using the unidirectional state flow pattern. It utilizes a `Store` to manage the `CollectionState` and sends actions to modify item counts and add new items. Dependencies include SwiftUI and the 'UnidirectionalFlow' library. ```swift @MainActor struct CollectionView: View { @State private var store = Store( initialState: CollectionState(), reducer: combinedCollectionReducer, middlewares: [] ) var body: some View { List { ForEach(store.itemsArray.indices, id: \.self) { index in HStack { Text(store.itemsArray[index].title) Spacer() Text("\(store.itemsArray[index].count)") Button("+") { Task { await store.send(.arrayItem(index: index, action: .increment)) } } } } } .onAppear { Task { await store.send(.addItem(ItemState(id: "1", title: "First", count: 0))) await store.send(.addItem(ItemState(id: "2", title: "Second", count: 0))) } } } } ``` -------------------------------- ### SwiftUI Form State Management with Unidirectional Flow Source: https://context7.com/mecid/swift-unidirectional-flow/llms.txt This Swift code defines the state, actions, and reducer for a form managed by the UnidirectionalFlow library. It includes a `FormState` struct for holding form data, a `FormAction` enum for defining possible state transitions, and a `FormReducer` to process these actions. The `FormView` utilizes `@State` and `store.binding` to create two-way bindings between SwiftUI controls and the form state, ensuring automatic state updates and action dispatching. ```swift import UnidirectionalFlow import SwiftUI struct FormState: Equatable { var username: String = "" var email: String = "" var agreedToTerms: Bool = false var selectedOption: Int = 0 } enum FormAction: Equatable { case setUsername(String) case setEmail(String) case setAgreedToTerms(Bool) case setSelectedOption(Int) case submit } struct FormReducer: Reducer { func reduce(oldState: FormState, with action: FormAction) -> FormState { var state = oldState switch action { case let .setUsername(username): state.username = username case let .setEmail(email): state.email = email case let .setAgreedToTerms(agreed): state.agreedToTerms = agreed case let .setSelectedOption(option): state.selectedOption = option case .submit: break // Handle submission } return state } } @MainActor struct FormView: View { @State private var store = Store( initialState: FormState(), reducer: FormReducer(), middlewares: [] ) var body: some View { Form { Section("Account Details") { TextField( "Username", text: store.binding( extract: { $0.username }, embed: { .setUsername($0) } ) ) TextField( "Email", text: store.binding( extract: { $0.email }, embed: { .setEmail($0) } ) ) } Section("Preferences") { Picker( "Option", selection: store.binding( extract: { $0.selectedOption }, embed: { .setSelectedOption($0) } ) ) { Text("Option 1").tag(0) Text("Option 2").tag(1) Text("Option 3").tag(2) } Toggle( "Agree to Terms", isOn: store.binding( extract: { $0.agreedToTerms }, embed: { .setAgreedToTerms($0) } ) ) } Section { Button("Submit") { Task { await store.send(.submit) } } .disabled(!store.agreedToTerms || store.username.isEmpty) } } } } ``` -------------------------------- ### Swift: Item and Collection State Management with Reducers Source: https://context7.com/mecid/swift-unidirectional-flow/llms.txt Defines the state and actions for individual items and a collection of items, along with reducers to handle state transformations. This allows for managing arrays and dictionaries of state objects. Dependencies include the 'UnidirectionalFlow' library. ```swift import UnidirectionalFlow // State for individual item struct ItemState: Equatable { let id: String var title: String var count: Int } enum ItemAction: Equatable { case increment case decrement case setTitle(String) } struct ItemReducer: Reducer { func reduce(oldState: ItemState, with action: ItemAction) -> ItemState { var state = oldState switch action { case .increment: state.count += 1 case .decrement: state.count -= 1 case let .setTitle(title): state.title = title } return state } } // Parent state with collection struct CollectionState: Equatable { var itemsArray: [ItemState] = [] var itemsDict: [String: ItemState] = [: ] } enum CollectionAction: Equatable { case arrayItem(index: Int, action: ItemAction) case dictItem(key: String, action: ItemAction) case addItem(ItemState) case removeItem(id: String) } // Array-based reducer using offset let arrayPrism = Prism( embed: { CollectionAction.arrayItem(index: $0, action: $1) }, extract: { action in guard case let .arrayItem(index, itemAction) = action else { return nil } return (index, itemAction) } ) let offsetReducer = ItemReducer().offset( keyPath: \CollectionState.itemsArray, prism: arrayPrism ) // Dictionary-based reducer using keyed let dictPrism = Prism( embed: { CollectionAction.dictItem(key: $0, action: $1) }, extract: { action in guard case let .dictItem(key, itemAction) = action else { return nil } return (key, itemAction) } ) let keyedReducer = ItemReducer().keyed( keyPath: \CollectionState.itemsDict, prism: dictPrism ) // Main collection reducer struct CollectionReducer: Reducer { func reduce(oldState: CollectionState, with action: CollectionAction) -> CollectionState { var state = oldState switch action { case let .addItem(item): state.itemsArray.append(item) state.itemsDict[item.id] = item case let .removeItem(id): state.itemsArray.removeAll { $0.id == id } state.itemsDict.removeValue(forKey: id) default: break } return state } } // Combine all reducers let combinedCollectionReducer = CombinedReducer( reducers: CollectionReducer(), offsetReducer, keyedReducer ) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.