Modello coordinatore in iOS

Feb 26 2023
Ciao ragazzi! Cos'è un coordinatore? Il coordinatore è un componente di sistema che contiene la logica di navigazione di un'applicazione. Il modello è stato introdotto da Soroush Khanlou.

Ciao ragazzi!

Cos'è un coordinatore?

Il coordinatore è un componente di sistema che contiene la logica di navigazione di un'applicazione. Il modello è stato introdotto da Soroush Khanlou .

Perché abbiamo bisogno di un coordinatore?

Il vantaggio dell'utilizzo del modello di coordinatore è che rimuoviamo la responsabilità della navigazione dai controllori. In questo modo possiamo aumentare la loro riusabilità inoltre possiamo avere la navigazione dell'app in un posto centrale, o abbiamo un coordinatore o abbiamo un coordinatore principale con i bambini.

Il disaccoppiamento dei controller di visualizzazione dalla navigazione dell'app può aumentare la leggibilità del progetto. Nelle app più grandi, è essenziale disporre della navigazione dell'app in un componente separato del sistema, soprattutto se sono presenti team di funzionalità.

L'obiettivo è poter cambiare facilmente la navigazione della logica a seconda della situazione. Ad esempio, utenti diversi possono avere flussi diversi o utenti iPad o test A/B isolati.

Principali caratteristiche di un Coordinatore.

  • Un coordinatore può avere molti ViewController.
  • I coordinatori hanno un metodo start in cui visualizzano inizialmente il ViewController.
  • I ViewController hanno un riferimento a un coordinatore.
  • Il coordinatore ha una serie di coordinatori figli.
  • I coordinatori dei bambini hanno un riferimento al loro genitore.

protocol Coordinator: AnyObject {
    var childCoordinators: [Coordinator] { get set }
    var navigationController: UINavigationController { get set }
    
    func start()
}

final class AppCoordnator: Coordinator {
    // 1
    var childCoordinators = [Coordinator]()
    
    // 2
    var navigationController: UINavigationController
        
    // 3
    init(navigationController: UINavigationController) {
        self.navigationController = navigationController
    }
    
    // 4
    func start() {
        let controller = StartViewController() 
        controller.coordinator = self
        navigationController.pushViewController(controller, animated: true)
    }
}

  1. L'elemento dell'interfaccia utente in cui verranno incorporati i ViewController.
  2. Inserito l'elemento UI nel costruttore.
  3. Il metodo start è dove avviene l'inizializzazione del ViewController e la connessione con il navigationController.

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

    // ...

    let navigationController = UINavigationController()
    let appCoordinator = AppCoordinator(navigationController: navigationController)
    appCoordinator.applicationRunnerDelegate = self
    appCoordinator.start()

    window?.rootViewController = appCoordinator.navigationController
    // ... 
}

Coordinatori con UITabBarController

Per beneficiare del modello di coordinatore quando abbiamo un UITabBarController come componente principale dell'interfaccia utente dell'app, dovremmo creare per ogni scheda un coordinatore. Vedere l'esempio seguente:

final class MainTabBarController: UITabBarController {
    
    private let dashboardCoordinator: DashboardCoordnator
    private let settingsCoordinator: SettingsCoordnator

    init() {
        self.dashboardCoordinator = DashboardCoordnator(navigationController: NavigationController())
        self.settingsCoordinator = SettingsCoordnator(navigationController: NavigationController())
        super.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        // ...

        viewControllers = [
            makeDashboardCoordinator(),
            makeSettingsCoordinator()
        ]
    }
    
    private func makeDashboardCoordinator() -> UINavigationController {
        let tabImage = "dashboard_tab_icon"

        let icon = UITabBarItem(title: "DASHBOARD",
                                image: UIImage(named: tabImage)?.withRenderingMode(.alwaysOriginal),,
                                selectedImage: UIImage(named: tabImage))
        dashboardCoordinator.navigationController.tabBarItem = icon
        dashboardCoordinator.start()
        return dashboardCoordinator.navigationController
    }
    
    private func makeSettingsCoordinator() -> UINavigationController {
        let tabImage = "settings_tab_icon"

        let icon = UITabBarItem(title: "SETTINGS",
                                image: UIImage(named: tabImage)?.withRenderingMode(.alwaysOriginal),
                                selectedImage: UIImage(named: tabImage))
        settingsCoordinator.navigationController.tabBarItem = icon
        settingsCoordinator.start()
        return settingsCoordinator.navigationController
    }
}

Separare la logica di navigazione da ViewControllers aumenta la coesione della classe e riduce l'accoppiamento del sistema. Mantiene la logica di navigazione in una posizione centrale e migliora la riusabilità e la testabilità.

Per qualsiasi commento, suggerimento o altro...

Colleghiamo:

Instagram:https://www.instagram.com/gvardikos/

LinkedIn:https://www.linkedin.com/in/george-vardikos-b0b199b0/

E-mail: [email protected]