App Architecture with MVVM
A clean architecture keeps apps maintainable as they grow. In this final lesson you'll structure a SwiftUI app with MVVM — separating the Model , View , and ViewModel — using ObservableObject view models for separation of concerns and easy testing.
Learn App Architecture with MVVM in our free Swift course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…
Part of the free Swift course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
What You'll Learn in This Lesson
1️⃣ The Model
The Model is pure data and domain rules. It imports no UI framework, so it can be reused and tested anywhere.
2️⃣ The ViewModel
The ViewModel is an ObservableObject that prepares model data for the view and holds presentation logic. Its @Published state drives the UI.
Your turn. Fill in the protocol and the publishing wrapper.
3️⃣ The View (and Testing the ViewModel)
The View stays thin: it shows ViewModel state and forwards actions. Because the ViewModel is UI-independent, you can unit-test its logic directly with XCTest.
Now you try. Fill in the wrapper that owns the view model and the method call.
📋 Quick Reference: MVVM Recap
Structure a small weather screen as Model, ViewModel, and View, then test the ViewModel — the perfect capstone for the track.
Practice quiz
What do the three letters in MVVM stand for?
- Model-View-ViewModel
- Model-Value-View-Module
- Main-View-Model-Manager
- Module-View-ViewMaker
Answer: Model-View-ViewModel. MVVM is Model, View, and ViewModel.
What is the Model's responsibility?
- Drawing the UI
- Representing the app's data and business rules
- Handling taps
- Storing view state only
Answer: Representing the app's data and business rules. The Model holds data and domain logic, independent of the UI.
What does the View do in MVVM?
- Stores the database
- Displays state and forwards user actions
- Performs networking
- Owns business rules
Answer: Displays state and forwards user actions. The View shows what the ViewModel exposes and relays user input.
What is the ViewModel's job?
- Render pixels
- Prepare data for the view and hold presentation logic
- Define the storage schema
- Replace the Model entirely
Answer: Prepare data for the view and hold presentation logic. The ViewModel transforms model data into view-ready state and handles presentation logic.
Which protocol do SwiftUI view models commonly adopt?
- Codable
- Hashable
- ObservableObject
- Sendable
Answer: ObservableObject. ObservableObject lets a view model publish changes that the view observes.
Inside an ObservableObject, which wrapper publishes a property's changes?
- @State
- @Published
- @Binding
- @Environment
Answer: @Published. @Published broadcasts changes so observing views refresh.
Which wrapper does a SwiftUI view use to observe a view model it creates and owns?
- @State
- @StateObject
- @Published
- @FetchRequest
Answer: @StateObject. @StateObject creates and owns an ObservableObject for the view's lifetime.
A key benefit of MVVM is...
- Fewer files always
- No need for models
- Faster compile times guaranteed
- Separation of concerns and easier testing of logic
Answer: Separation of concerns and easier testing of logic. MVVM separates UI from logic, making the logic easy to test in isolation.
Why is a ViewModel easy to unit test?
- It holds plain logic with no UI dependency
- It imports SwiftUI heavily
- It runs on the GPU
- It cannot be tested
Answer: It holds plain logic with no UI dependency. Because a ViewModel is UI-independent, you can test its logic directly without rendering views.
In MVVM, the View should ideally contain...
- All business logic
- The data model
- Little logic — mostly layout bound to ViewModel state
- The networking code
Answer: Little logic — mostly layout bound to ViewModel state. Views stay thin, delegating logic to the ViewModel for testability and clarity.