Photo by Joshua Reddekopp on Unsplash

The basis of MVVM in SwiftUI

Maxime Tanter
3 min readApr 6, 2023

--

MVVM (Model-View-ViewModel) is a popular design pattern that has gained a lot of traction in recent years, particularly in the context of iOS development. In this article, we’ll discuss what MVVM is and how it can be implemented in SwiftUI.

Please note that I am not saying that the mvvm pattern is the best design pattern to use in SwiftUI, each application is different and has specific needs :)

What is MVVM?

MVVM is a design pattern that separates an application into three primary components: the Model, the View, and the ViewModel. The Model represents the data and business logic of the application. The View is responsible for displaying the user interface to the user. The ViewModel acts as a mediator between the Model and the View, handling user interactions and providing data to the View.

The Benefits of Using MVVM

Using MVVM has a number of benefits, including:

  • Separation of concerns: MVVM separates the concerns of the Model, View, and ViewModel, making it easier to maintain and modify the codebase.
  • Testability: Because the ViewModel acts as a mediator between the Model and View, it can be easily tested in isolation from the rest of the application.
  • Reusability: By separating the concerns of the application, components can be reused more easily across different parts of the application.

Implementing MVVM

in SwiftUI In SwiftUI, implementing MVVM is relatively straightforward. Here’s an example of how it can be done:

1 — Create a Model

The Model represents the data and business logic of the application. In our example, we’ll create a simple Model that represents a user:

struct User {
let name: String
let age: Int
}

2 — Create a ViewModel

The ViewModel acts as a mediator between the Model and the View. It is responsible for providing data to the View and handling user interactions. In our example, we’ll create a simple ViewModel that exposes a User object and a function for updating the User’s age:

class UserViewModel: ObservableObject {
@Published var user: User

init(user: User) {
self.user = user
}

func updateUserAge(age: Int) {
user.age = age
}
}

3 — Create a View

The View is responsible for displaying the user interface to the user. In our example, we’ll create a simple View that displays the user’s name and age and allows the user to update their age:

struct UserView: View {
@ObservedObject var viewModel: UserViewModel

var body: some View {
VStack {
Text("Name: \(viewModel.user.name)")
Text("Age: \(viewModel.user.age)")
Stepper(value: $viewModel.user.age, in: 0...120) {
Text("Update Age")
}
}
}
}

4 — Putting it all Together

Now that we have our Model, ViewModel, and View, we can put them all together:

struct ContentView: View {
var body: some View {
let user = User(name: "John", age: 30)
let viewModel = UserViewModel(user: user)
UserView(viewModel: viewModel)
}
}

In this example, we create a User object, pass it to a UserViewModel, and then pass the ViewModel to a UserView. The UserView displays the user’s name and age and allows the user to update their age using a Stepper.

Conclusion

MVVM is a powerful design pattern that can help make your code more maintainable, testable, and reusable. In SwiftUI, implementing MVVM is relatively straightforward, and can help you build robust and scalable applications.

This article is really the basis of the implementation of the MVVM pattern in SwiftUI. Obviously there are many things to consider if you’re developing an iOS app, but hopefully this helps you understand the separation of principles here.
If you want me to go deeper into the subject, don’t hesitate to let me know in the comments :)

--

--

Maxime Tanter

Hi ! My name is Maxime. I’m an iOS developer, from France. Passionate about apple stuff and iOS development.