SwiftUI Data Flow, Navigation and Architecture

50.1 State Management

Local value-type state owned by the view (and @Observable model instances owned by a view)

Two-way reference to state owned elsewhere ($value) @Observable (Observation, iOS 17+)

Model classes with automatic fine-grained change tracking Create bindings to @Observable properties

Read environment values or injected objects (@Environment(Store.self)) @AppStorage / @SceneStorage

UserDefaults-backed / scene-restoration state @FocusState, @GestureState, @Namespace Focus, gestures, animations

Legacy (pre-iOS 17): ObservableObject, @Published, @StateObject, @ObservedObject, @EnvironmentObject

@Observable
final class CartStore {
    var items: [Product] = []
    var total: Decimal { items.reduce(0) { $0 + $1.price } }
    func add(_ p: Product) { items.append(p) }
}

struct ShopView: View {
    @State private var cart = CartStore()           // owns the model
    var body: some View {
        ProductList()
            .environment(cart)                       // inject it
    }
}

struct ProductList: View {
    @Environment(CartStore.self) private var cart
    let products: [Product] = Product.samples
    var body: some View {
        List(products) { product in
            Button("Add \(product.name)") { cart.add(product) }
        }
        .safeAreaInset(edge: .bottom) { Text("Total: \(cart.total, format: .currency(code: "USD"))") }
    }
}

struct EditProductView: View {
    @Bindable var product: ProductModel             // @Observable class
    var body: some View { TextField("Name", text: $product.name) }
}

50.2 Navigation

enum Route: Hashable { case detail(Product), settings }

struct RootView: View {
    @State private var path: [Route] = []
    var body: some View {
        NavigationStack(path: $path) {
            List(Product.samples) { product in
                NavigationLink(product.name, value: Route.detail(product))
            }
            .navigationDestination(for: Route.self) { route in
                switch route {
                case .detail(let p): ProductDetail(product: p)
                case .settings: SettingsView()
                }
            }
            .toolbar { Button("Settings") { path.append(.settings) } }
        }
    }
}

50.3 Architecture Patterns

MV (Model-View) with @Observable, MVVM (view models as @Observable/@MainActor classes), The Composable Architecture (TCA) by Point-Free (reducers, state, actions, effects, dependencies), Clean Architecture/VIPER (UIKit-era), Coordinator pattern for navigation.

Dependency injection: environment values, initializer injection, swift-dependencies library, protocol-based services for testability.

Previews with sample data (#Preview + mock services), modularization with local Swift packages (feature modules).