Modèle de coordinateur dans iOS

Feb 26 2023
Salut les gars ! Qu'est-ce qu'un coordinateur ? Le coordinateur est un composant système qui contient la logique de navigation d'une application. Le motif a été introduit par Soroush Khanlou.

Salut les gars !

Qu'est-ce qu'un coordinateur ?

Le coordinateur est un composant système qui contient la logique de navigation d'une application. Le motif a été introduit par Soroush Khanlou .

Pourquoi avons-nous besoin d'un coordinateur ?

L'avantage d'utiliser le modèle de coordinateur est que nous supprimons la responsabilité de la navigation des contrôleurs. De cette façon, nous pouvons augmenter leur réutilisabilité et nous pouvons avoir la navigation de l'application dans un endroit central, soit nous avons un coordinateur, soit nous avons un coordinateur principal avec les enfants.

Le découplage des contrôleurs de vue de la navigation de l'application peut augmenter la lisibilité du projet. Dans les grandes applications, il est essentiel d'avoir la navigation de l'application dans un composant séparé du système, surtout s'il y a des équipes de fonctionnalité.

Le but est de pouvoir changer la navigation de la logique facilement en fonction de la situation. Par exemple, différents utilisateurs peuvent avoir différents flux ou utilisateurs d'iPad ou tests A/B isolés.

Principales caractéristiques d'un Coordonnateur.

  • Un coordinateur peut avoir plusieurs ViewControllers.
  • Les coordinateurs ont une méthode de démarrage dans laquelle ils affichent initialement le ViewController.
  • Les ViewControllers ont une référence à un coordinateur.
  • Le coordinateur dispose d'un éventail d'enfants coordinateurs.
  • Les coordonnateurs des enfants ont une référence à leur parent.

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'élément d'interface utilisateur dans lequel les ViewControllers seront intégrés.
  2. Injecté l'élément UI dans le constructeur.
  3. La méthode de démarrage est l'endroit où l'initialisation du ViewController et la connexion avec le navigationController se produisent.

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
    // ... 
}

Coordinateurs avec UITabBarController

Afin de bénéficier du modèle de coordinateur lorsque nous avons un UITabBarController comme composant principal de l'interface utilisateur de l'application, nous devons créer un coordinateur pour chaque onglet. Voir l'exemple ci-dessous :

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
    }
}

Séparer la logique de navigation des ViewControllers augmente la cohésion de classe et réduit le couplage du système. Maintient la logique de navigation dans un endroit central et améliore la réutilisabilité et la testabilité.

Pour tout commentaire, suggestion ou autre...

Connectons-nous :

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

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

Courriel : [email protected]