Unpacking Redux and MVVM - A comparative look at the 2 architectures in Swift
Thomas Henry Oz Sandvik
Software Platform Architect at Terma | iOS & Apple Mobile/Web Technologies | Exploring AI
I've set a goal to dig deeper into Redux, a pattern I've recently come across. My focus will be to understand its role in app architecture and state management. This exploration is part of my preparation for an upcoming personal project where I will consider using this new knowledge.
For the uninitiated, Redux is a popular JavaScript library for managing application state, but it's also found a home in Swift development. While I was diving into Redux, I realized it would be a great idea to compare it with another well-known architectural pattern - Model-View-ViewModel or MVVM, that I am more comfortable with..?Now, MVVM is a hit in the Swift community, especially with the introduction of SwiftUI and the Combine framework.
The purpose of this article, then, is to share my newfound insights about Redux and MVVM in Swift, comparing the two side by side, and discussing their pros and cons. My aim is to provide a guide that'll help you, like it helped me to make an informed choice about pattern for an app.?
Whether you're just dipping your toes into Swift, or you're a seasoned pro looking for a refresher, read on. Let's delve into Redux and MVVM in Swift!
Buckle up!
Redux in Swift
It sticks to three main principles:
Why Redux Rocks
Redux Downsides
Despite these cool things, Redux does add (too much?) complexity to your codebase, so it might be overkill for simpler apps. Plus, if your app's state doesn't change much or doesn't need to be shared across many components, Redux may not be the best fit.
MVVM in Swift
MVVM is a crowd favorite in the Swift community. With SwiftUI and the Combine framework, it's become even more popular. Here's what it looks like:
Why MVVM is Great
MVVM's Downsides
While MVVM has some solid strengths, it's not all sunshine and roses:
Some code would be nice
How Redux could look like
// Stat
struct AppState {
????var counter: Int = 0
}
// Actions
enum AppAction {
????case increment
????case decrement
}
// Reducer
func appReducer(state: inout AppState, action: AppAction) {
????switch action {
????case .increment:
????????state.counter += 1
????case .decrement:
????????state.counter -= 1
????}
}
// Usage
struct ContentView: View {
????@State private var state = AppState()
????var body: some View {
????????VStack {
????????????Text("Counter: \(state.counter)")
????????????Button("Increment") {
????????????????appReducer(state: &state, action: .increment)
????????????}
????????}
????}
}
How MVVM could look like
// Model
struct Counter {
? ? var value: Int = 0
}
// ViewModel
class CounterViewModel: ObservableObject {
? ? @Published var counter: Counter = Counter()
? ? func increment() {
? ? ? ? counter.value += 1
? ? }
? ? func decrement() {
? ? ? ? counter.value -= 1
? ? }
}
struct ContentView: View {
? ? @ObservedObject var viewModel: CounterViewModel
? ? ? ? var body: some View {
? ? ? ? ? ? VStack {
? ? ? ? ? ? ? ? Text("Counter: \(viewModel.counter.value)")
? ? ? ? ? ? ? ? Button("Increment", action: viewModel.increment)
? ? ? ? ? ? ? ? Button("Decrement", action: viewModel.decrement)
? ? ? ? ? ? }
? ? ? ? }
}
The Final Face-off
So, Redux and MVVM - which one should you go with? Well, it depends on what your app needs, your personal coding style, and your project's specific requirements.
Redux is a state management champ. It brings predictability and ease of debugging to the table, but it can also bring a lot of complexity if your app is a simple one. On the other hand, MVVM plays nice with Combine, offering a clear separation of concerns that helps with code maintenance and testability. But, beware of those oversized ViewModels.
Remember, architecture choices are like clothes. What works for one person might not work for another. It's all about understanding what your project needs and picking the architecture that fits those needs like a glove. There's no one-size-fits-all answer here - every project is unique, and so should be its architecture.?
Happy coding!