Что такое Coordinator в архитектуре iOS и для чего он нужен
Что проверяют
Понимаете ли вы, какую проблему решает координатор: экраны, которые сами создают и показывают следующие экраны, становятся связанными и не переиспользуются. Следом спрашивают про память, системный жест «Назад» и про то, как координатор уживается со SwiftUI.
Как отвечать
Coordinator это объект, который владеет навигацией одного сценария: создаёт контроллеры, передаёт им зависимости и решает, куда идти дальше. Контроллер про соседей не знает, он только сообщает «пользователь выбрал товар» через замыкание или делегат. Паттерн популяризовал Soroush Khanlou в 2015 году.
- базовый протокол:
start()и массивchildCoordinators. КорневойAppCoordinatorрешает, показать онбординг, авторизацию или главный экран; - дерево: каждый поток (регистрация, оформление заказа) живёт в своём дочернем координаторе, который по завершении сообщает родителю и удаляется из массива;
- что даёт: один экран работает в разных сценариях, диплинк разбирается в одном месте, переходы проверяются тестом с подменённым
UINavigationController; - с MVVM получается MVVM-C: ViewModel отдаёт событие, координатор выполняет переход;
- в SwiftUI с iOS 16 навигацией управляет
NavigationStack(path:). Роль координатора берёт объект, который владеетNavigationPathили массивом маршрутов, а экраны строятся вnavigationDestination.
Цена: лишний слой и шаблонный код, для приложения из трёх экранов это перебор.
Где спотыкаются
Делают сильную ссылку из контроллера на координатор, как в популярных примерах с vc.coordinator = self. Координатор держит навигационный стек, стек держит контроллер, контроллер держит координатор, и получается цикл. Ссылка должна быть weak, а ещё проще передать замыкание.
Забывают про свайп назад. Пользователь смахнул экран, контроллер ушёл из стека, а дочерний координатор остался в childCoordinators и живёт вечно. Отслеживают это через UINavigationControllerDelegate и метод navigationController(_:didShow:animated:).
Превращают AppCoordinator в класс на тысячу строк со всеми переходами приложения. Смысл паттерна в том, что каждый поток изолирован и отвечает только за свой кусок навигации.