Patrón de coordinador de iOS
En el artículo de hoy, exploremos el patrón del coordinador en detalle. Veremos cómo configurar un coordinador desde cero y veremos los aspectos positivos de implementarlo en proyectos de iOS.
Fondo…….
Como todos sabemos, los patrones de diseño de iOS más utilizados son MVVM y MVC (a veces podría ser un controlador de vista masivo ). Uno de los mayores inconvenientes de estos patrones es que los controladores mantienen la lógica para el enrutamiento. Aquí, el enrutamiento puede inicializarse y manejar el siguiente controlador en el flujo comercial.
Patrón coordinador…….
El patrón del coordinador supera este problema al abstraer la lógica de enrutamiento. Aquí todos los controladores de vista que se pueden agrupar lógicamente bajo un flujo de negocios se coordinan con el coordinador. El Coordinador es el único responsable del próximo controlador en el flujo comercial. Esto hace que la lógica de enrutamiento sea más legible, mantenible y extensible.
Coordinador DAN….
Coordinador en acción…..
Ahora veamos cómo podemos configurar un patrón coordinador desde cero.
Protocolo de coordinadores: creemos una interfaz para nuestros coordinadores que exija que todos los coordinadores estén alineados con nuestras expectativas.
- navController: este sería el controlador de navegación para administrar la pila del controlador de vista.
- eventOccurred (T): esto sería utilizado por nuestro controlador de vista para actualizar cualquier evento de navegación al coordinador
- start (): este método único en la vida se llama para iniciar el flujo comercial
protocol Coordinator {
var navController : UINavigationController? { get set }
func eventOccurred<T: RawRepresentable>(type: T) where T.RawValue == Int
func start()
}
protocol Coordinating {
var coordinator: Coordinator? { get set}
}
typealias CoordinatingVC = UIViewController & Coordinating
class ViewController: CoordinatingVC {
var coordinator: Coordinator?
override func viewDidLoad() {
super.viewDidLoad()
setUp()
setUpCTA()
}
private func setUp() {
self.view.backgroundColor = .white
self.title = "Screen1"
}
private func setUpCTA() {
let screen2CTA = UIButton()
screen2CTA.setTitle("Go to Screen2", for: .normal)
screen2CTA.backgroundColor = .gray
view.addSubview(screen2CTA)
screen2CTA.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
screen2CTA.leadingAnchor.constraint(equalTo: view.leadingAnchor,
constant: AppUIConfig.padding),
screen2CTA.trailingAnchor.constraint(equalTo: view.trailingAnchor,
constant: -AppUIConfig.padding),
screen2CTA.centerYAnchor.constraint(equalTo: view.centerYAnchor),
screen2CTA.heightAnchor.constraint(equalToConstant: AppUIConfig.buttonheight)
])
screen2CTA.addTarget(self,
action: #selector(screen2CTATapped),
for: .touchUpInside)
}
@objc func screen2CTATapped() {
coordinator?.eventOccurred(type: MainCoordinatorEvent.screen2)
}
}
enum MainCoordinatorEvent: Int {
case screen2
case screen1
}
class MainCoordinator : Coordinator {
func eventOccurred<T>(type: T) where T : RawRepresentable, T.RawValue == Int {
guard let type = type as? MainCoordinatorEvent else {
return
}
switch type {
case .screen2:
setupScreen2()
case .screen1:
setupScreen1()
}
}
var navController: UINavigationController?
func start() {
setupScreen1()
}
private func setupScreen1() {
guard var navController = navController else {
return
}
if let firstVC = navController.viewControllers.first {
navController.popToViewController(firstVC, animated: true)
return
}
var viewController: CoordinatingVC = ViewController()
viewController.coordinator = self
navController.setViewControllers([viewController], animated: false)
}
private func setupScreen2() {
var viewController: CoordinatingVC = ViewController2()
viewController.coordinator = self
navController?.pushViewController(viewController, animated: true)
}
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
setUpWindow()
return true
}
private func setUpWindow() {
let window = createKeyWindow()
let mainCoordinator = createMainCoordinator()
window.rootViewController = mainCoordinator.navController
window.makeKeyAndVisible()
self.window = window
mainCoordinator.start()
}
private func createMainCoordinator() -> Coordinator {
let navViewController = UINavigationController()
let mainCoordinator = MainCoordinator()
mainCoordinator.navController = navViewController
return mainCoordinator
}
private func createKeyWindow() -> UIWindow {
let window = UIWindow(frame: UIScreen.main.bounds)
return window
}
Ahora que sabemos cómo administrar un flujo de negocios usando un patrón coordinador. Podemos extender el patrón recursivamente para administrar grupos de coordinadores, simplificando así cada flujo de usuario agrupado lógicamente para administrarlo por sí solo.
Seguir el patrón del coordinador en las aplicaciones de iOS hace que el enrutamiento entre los flujos de usuarios sea más limpio y sólido. Esto hace que cada controlador de vista esté realmente aislado y sea fácil de mantener.
Referencias :
https://www.hackingwithswift.com/articles/71/how-to-use-the-coordinator-pattern-in-ios-apps
https://www.youtube.com/watch?v=SAZzcKvOvAE

![¿Qué es una lista vinculada, de todos modos? [Parte 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































