SwiftUI – MVVM

In this post, we will see how to implement MVVM pattern in SwiftUI.
But, what is MVVM pattern?
From wikipedia:
Model–view–viewmodel (MVVM) is a software architectural pattern that facilitates the separation of the development of the graphical user interface (the view) – be it via a markup language or GUI code – from the development of the business logic or back-end logic (the model) so that the view is not dependent on any specific model platform. The viewmodel of MVVM is a value converter, meaning the viewmodel is responsible for exposing (converting) the data objects from the model in such a way that objects are easily managed and presented. In this respect, the viewmodel is more model than view, and handles most if not all of the view’s display logic. The view model may implement a mediator pattern, organizing access to the back-end logic around the set of use cases supported by the view.


In this post, we will create a simple list of Users using this pattern.
We start creating an iOS application, where we will define the MVVM components:

[Model – User.swift]

import Foundation

struct User: Identifiable {
    var id: Int
    var Username:String
    var Password:String
}


[View Model – UserViewModel.swift]

import Foundation

class UserViewModel {
    
    private var lstUser = [User]()
    
    // constructor
    init() {
        // here, we feed the list of users
        for index in 1...10 {
            lstUser.append(User(id: index, Username: "Username_\(index)", Password: "Password_12\(index)"))
        }
    }
    
    func GetAllUsers() -> [User] {
        return lstUser
    }
}


[View – ContentView.swift]

import SwiftUI

// OBVIOUSLY, IN THIS POST THE UI STYLE IT ISN'T THE MAIN GOAL!

struct ContentView: View {
    @State var viewModel = UserViewModel()
    var body: some View {
        NavigationView{
            // we call the method GetAllUsers
            List(viewModel.GetAllUsers()) { item in
                        HStack {
                            Text("ID: \(item.id)")
                            VStack {
                                Text(item.Username)
                                Text(item.Password)
                            }.padding(.leading, 20)
                        }.padding(.leading, 10)
                    }.navigationBarTitle("Users List")
                }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}



We have done and now, if we run the application, this will be the result: