SwiftUI MVVM Architecture

SwiftUI MVVM Architecture

As your SwiftUI app grows, putting all your logic, networking, and data formatting directly inside your Views becomes a massive mess.

To keep code clean, testable, and highly organized, developers use design patterns.

The most popular and highly recommended architecture for SwiftUI is MVVM (Model-View-ViewModel).


The Three Pillars of MVVM

MVVM separates your application into three distinct layers:

The golden rule of MVVM is: Views should not do any heavy lifting. They should only display what the ViewModel tells them to display.


Creating the ViewModel

A ViewModel is typically created as a class that conforms to the ObservableObject protocol.

Inside, you mark any data that the UI needs to display with the @Published property wrapper.

The ViewModel:

import Foundation

class CounterViewModel: ObservableObject { // The view will automatically update when this changes @Published var count: Int = 0 // Business logic belongs here, not in the View! func increment() { count += 1 } func reset() { count = 0 } }


Connecting the View

To connect your UI to the ViewModel, you instantiate it inside your SwiftUI View using the @StateObject property wrapper.

@StateObject ensures that SwiftUI keeps the ViewModel alive in memory even if the View itself is destroyed and redrawn.

The View:

import SwiftUI

struct CounterView: View { // Creating and owning the ViewModel @StateObject private var viewModel = CounterViewModel() var body: some View { VStack(spacing: 20) { // Reading data from the ViewModel Text("Count: \(viewModel.count)") .font(.largeTitle) // Triggering intents (actions) on the ViewModel Button("Add 1") { viewModel.increment() } } } }


Why Use MVVM?

By moving functions like increment() out of the View and into the ViewModel, you make your code infinitely easier to test.

You can write a simple unit test for CounterViewModel without needing to simulate button taps or UI rendering!


Exercise

In the MVVM pattern, which component is responsible for holding business logic and notifying the UI of data changes?