Arquitectura MVVM para Desarrollo de apps

Autor: | Última modificación: 26 de octubre de 2022 | Tiempo de Lectura: 3 minutos
Temas en este post:

¿Qué es la arquitectura MVVM?  Para mi gusto, es el futuro de las arquitecturas de desarrollo de aplicaciones. Llevo ya tiempo usando esta arquitectura y me parece muy cómoda, que es su principal ventaja  sobre VIPER. También respeta los principios SOLID, es fácilmente testable y una de sus muchas ventajas es que se usa tanto en iOS como en Android ya que VIPER no llegó a gustarle a los desarrolladores Android por su complejidad.

Model

Este elemento es común en todas las arquitecturas de desarrollo. Se trata de una clase o struct que define las propiedades de un objeto. La definición de modelo es que debe ser una estructura de código sencilla, sin funcionalidad. Unicamente propiedades. Y en caso de tener que añadir algún tipo de funcionalidad la separaremos por extensiones dentro del mismo archivo o en archivos separados. Esta estructura debe ser tan sencilla que no debe dar problema al extender el protocolo Codable.

import Foundation

struct Person : Codable {
    
    var name : String
    var age : Int
    var height : Double
    
}

View Model

La principal tarea del view model es ejecutar toda la lógica de una pantalla. También tiene la función de llamar a servicios REST y de extraer datos de la base de datos. Aunque como recomendación, es mejor separar estas consultas en clases distintas para centralizar funcionalidades. El view model tiene contacto directo con el modelo y se comunica con la vista mediante un protocolo. También tiene contacto con el router para hacer cambios de pantallas.

import Foundation

class PersonViewModel {

    

    weak var view:PersonViewControllerProtocol!

    var router: PersonRouter!

    

    var person:Person!

    

    func loadView() {

        

        self.person = Person(name: "Alvaro", age: 22, height: 1.79)

        self.view.didLoadView()

        

    }

    

    func showNextScreen() {

        self.router.showPersonsList()

    }

    

}

INVITACIÓN bootcamp mobile (sesión informativa) - Arquitectura MVVM

VIEW

La vista es sencilla, ya que no debe tener lógica. Solo tiene las funciones de modificar los elementos de la vista según ordene el view model y de pasar las interacciones de la vista al view model para que este las procese y actúe en consecuencia. En mi caso me gusta que la vista conozca directamente al view model y evitar un protocolo intermedio. Aunque es buena práctica usar protocolos para las comunicaciones. El problema es que se vuelve pesado el desarrollo y puede llegar a resultar incómodo y realmente no cambia tanto el resultado ya que el único acceso que tiene la vista al view model y a usar sus variables y funciones públicas.

import UIKit

class PersonViewController : UIViewController {

    

    var viewModel:PersonViewModel!

    

    @IBOutlet weak var name: UILabel!

    @IBOutlet weak var age: UILabel!

    @IBOutlet weak var height: UILabel!

    

    override func viewDidLoad() {

        super.viewDidLoad()

        

        self.name.textColor = UIColor.red

        

        self.age.textColor = UIColor.orange

        

        self.height.textColor = UIColor.blue

        

        self.viewModel.loadView()

    }

    

    @IBAction func personButtonAction() {

        self.viewModel.showNextScreen()

    }

  

}




//MARK: - ViewModel communication

protocol PersonViewControllerProtocol : class {

    func didLoadView()

}




extension PersonViewController : PersonViewControllerProtocol {

    

    func didLoadView() {

        self.name.text = self.viewModel.person.name

        self.age.text = "\(self.viewModel.person.age) años"

        self.height.text = "\(self.viewModel.person.height) metros"

    }

}

ROUTER

El router también es un elemento común en arquitecturas y se encarga básicamente de la transición entre pantallas, de formar y relacionar a los elementos de la arquitectura y de proporcionar a cada elemento los datos necesarios para formar la pantalla.

import Foundation

class PersonRouter {

    

    weak var viewController : PersonViewController!

    

    static func getViewController() -> PersonViewController {

        

        let viewController = PersonViewController()

        let router = PersonRouter()

        let viewModel = PersonViewModel()

        

        viewController.viewModel = viewModel

        

        viewModel.router = router

        viewModel.view = viewController

        

        router.viewController = viewController

        

        return viewController

        

    }

    

    func showPersonsList() {

        let vc = PersonListRouter.getViewController()

        self.viewController.present(vc, animated: true, completion: nil)

    }

    

}

XCODE Y MVVM

Como ya sabemos XCode proporciona muchas herramientas para automatizar tareas, en este caso la creación de las clases. Podemos automatizar la creación usando templates. Si usamos por ejemplo MVVM con RxSwift podemos crear clases de las que heredar ciertas funcionalidades y crear un módulo usando cocoa pods.

Así que no hay excusas para usar arquitecturas limpias. Quizás tiene un poco de trabajo al principio pero luego se agradece.

Por: Álvaro Royo

Álvaro Royo

iOS Senior Developer | Instructor de “Superpoderes iOS” en el Bootcamp Desarrollo Mobile de KeepCoding

Si tienes algo que deseas compartir o quieres formar parte de KeepCoding, escríbenos a [email protected]