SwiftUI, Apple's modern UI framework for building user interfaces across all Apple platforms, supports various architecture patterns that help organize code more efficiently. Here are some key architecture patterns used in SwiftUI:
MVVM is one of the most popular architecture patterns in SwiftUI. In this pattern, the model represents the data, the view displays the interface, and the ViewModel interacts with the model and provides data to the view.
struct ContentView: View {
@StateObject var viewModel = MyViewModel()
var body: some View {
List(viewModel.items) { item in
Text(item.name)
}
.onAppear {
viewModel.fetchItems()
}
}
}
class MyViewModel: ObservableObject {
@Published var items: [Item] = []
func fetchItems() {
// Fetch data from a source
}
}
Inspired by Redux, the reducer pattern involves a central store and emphasizes state management through actions and reducers. This pattern is useful for complex state management.
struct AppState {
var count: Int = 0
}
enum Action {
case increment
case decrement
}
func reducer(state: inout AppState, action: Action) {
switch action {
case .increment:
state.count += 1
case .decrement:
state.count -= 1
}
}
struct ContentView: View {
@State private var state = AppState()
var body: some View {
VStack {
Text("Count: \(state.count)")
Button("Increment") {
reducer(state: &state, action: .increment)
}
Button("Decrement") {
reducer(state: &state, action: .decrement)
}
}
}
}
Using Combine alongside SwiftUI can enhance reactive programming. You can create publishers and subscribers for more responsive UI updates based on asynchronous data streams.
class DataLoader: ObservableObject {
@Published var data: [String] = []
func loadData() {
Just(["Item 1", "Item 2", "Item 3"])
.delay(for: .seconds(2), scheduler: RunLoop.main)
.assign(to: &$data)
}
}
struct ContentView: View {
@StateObject var loader = DataLoader()
var body: some View {
List(loader.data, id: \.self) { item in
Text(item)
}
.onAppear {
loader.loadData()
}
}
}
How do I avoid rehashing overhead with std::set in multithreaded code?
How do I find elements with custom comparators with std::set for embedded targets?
How do I erase elements while iterating with std::set for embedded targets?
How do I provide stable iteration order with std::unordered_map for large datasets?
How do I reserve capacity ahead of time with std::unordered_map for large datasets?
How do I erase elements while iterating with std::unordered_map in multithreaded code?
How do I provide stable iteration order with std::map for embedded targets?
How do I provide stable iteration order with std::map in multithreaded code?
How do I avoid rehashing overhead with std::map in performance-sensitive code?
How do I merge two containers efficiently with std::map for embedded targets?