One question comes up repeatedly in iOS architecture interviews.
“What is the difference between MVP and MVVM?”
Both patterns slim down view controllers and place an intermediary object (Presenter/ViewModel) in the middle. Looking only at the diagram, it seems like just one box has been renamed, which makes this surprisingly tricky to answer.
Today, let’s reduce the difference to one criterion: “Does the intermediary object know about the View or not?”
MVP: The Presenter commands the View
In MVP (Model-View-Presenter), the Presenter knows about the View. More precisely, it references a protocol (interface) implemented by the View.
protocol ProfileViewProtocol: AnyObject {
func showName(_ name: String)
func showLoading(_ isLoading: Bool)
}
final class ProfilePresenter {
weak var view: ProfileViewProtocol?
func load() {
view?.showLoading(true)
// ...After loading data
view?.showName("John Doe")
view?.showLoading(false)
}
}
Can you see the flow? After processing the data, the Presenter directly commands the view, “Display this”. The View (view controller) implements the protocol methods and simply renders what it is told.
- Advantage: The flow is explicit and easy to follow, with no binding framework required.
- Disadvantage: As the number of screen elements grows, protocol methods keep multiplying.
showName,showAge,showBadge…
MVVM: The ViewModel Does Not Know the View Exists
By contrast, the ViewModel in MVVM (Model-View-ViewModel) does not reference the View. It only holds state.
final class ProfileViewModel {
@Published private(set) var displayName = ""
@Published private(set) var isLoading = false
func load() {
isLoading = true
// ...After loading data
displayName = "John Doe"
isLoading = false
}
}
There is no call like view?.showName(...). The ViewModel updates only its own state, and the View subscribes to (binds to) that state and renders it automatically. The direction of the command is reversed.
- MVP: Push data to the View
- MVVM: The View observes the ViewModel to pull data
That is why MVVM effectively requires a binding mechanism (Combine, @Observable, and so on). The previous installment covered in detail why MVVM without binding is only half an implementation.
The Difference Becomes Clear in the Tests
Both patterns aim to test logic without a screen, but the testing approaches differ.
MVP tests create a fake View and record its calls.
final class MockView: ProfileViewProtocol {
var shownName: String?
func showName(_ name: String) { shownName = name }
func showLoading(_ isLoading: Bool) {}
}
// presenter.load() after mockView.shownName verification
MVVM tests are done by simply checking the state values, without mocks.
let vm = ProfileViewModel()
vm.load()
#expect(vm.displayName == "John Doe")
No protocol or mock object is needed. That is the practical benefit of the ViewModel not knowing about the View.
So Which One Should You Use?
The criterion is surprisingly simple: is a binding mechanism available naturally?
- SwiftUI, or UIKit with Combine → MVVM is the natural choice. Binding comes for free.
- Legacy UIKit where introducing binding feels burdensome → MVP is more practical. It runs on protocols alone, keeps the flow explicit, and is easy to onboard.
The reason MVVM has become something close to the de facto standard in modern iOS is less that it is superior to MVP and more that Combine and @Observable are provided at the framework level, removing MVVM’s only barrier to entry: binding.
Summary
- The essential difference between MVP and MVVM is just one thing. The Presenter knows the View (protocol) and commands it directly, while the ViewModel does not know the View and only exposes state.
- Therefore, MVP needs no binding, while MVVM requires it.
- In testing, MVP requires a mock View, while MVVM is complete with state verification alone.
- In an environment where binding is free (SwiftUI·Combine), choose MVVM; otherwise, MVP is still a perfectly good choice.
In the next installment, we’ll cover VIPER, the extreme form of modular separation that takes this one step further. We’ll also examine why large apps adopted it—and why they abandoned it.

![Cover image for [iOS Architecture #4] MVP vs MVVM: Key Differences](/assets/images/posts/4b118d20-6c27-4d0a-ad4a-7ec1b68ffb16/1.jpg)