Шаблон координатора
Централизуйте логику навигации.
«Шаблон координатора» — бесплатный урок Swift Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Swift Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Swift Academy содержит 4 уроков всего.
Проблема навигации
Когда представления напрямую открывают и отображают другие представления, логика навигации оказывается разрозненной по всему приложению. Каждый экран должен знать о следующем экране, что создаёт тесную связанность.
Паттерн координатора решает эту проблему, вынося навигацию в отдельные объекты.
Что такое координатор
Координатор — это объект, единственная задача которого — управлять потоком навигации. Он решает, какой экран должен появиться следующим, и создаёт контроллеры представлений или представления для отображения.
Представления больше не должны разбираться в маршрутизации — они лишь сообщают о событиях, а координатор решает, что делать.
Протокол координатора
Большинство реализаций начинается с небольшого протокола, которому соответствует каждый координатор.
protocol Coordinator: AnyObject {
var childCoordinators: [Coordinator] { get set }
func start()
}Конкретный координатор
Конкретный координатор владеет контроллером навигации и создаёт первый экран в start().
final class AppCoordinator: Coordinator {
var childCoordinators: [Coordinator] = []
let navigationController: UINavigationController
init(navigationController: UINavigationController) {
self.navigationController = navigationController
}
func start() {
let vc = HomeViewController()
navigationController.setViewControllers([vc], animated: false)
}
}Отделение представлений от маршрутизации
Главное преимущество: представление больше не создаёт следующий экран. Вместо этого оно сообщает своему координатору о произошедшем событии, а координатор выполняет маршрутизацию.
Это означает, что экран можно повторно использовать в разных потоках, не изменяя его код.
Передача событий вверх
Представления взаимодействуют со своим координатором через delegate или замыкание. Представление не знает, куда оно ведёт дальше.
protocol HomeViewControllerDelegate: AnyObject {
func homeDidSelectProfile()
}
final class HomeViewController: UIViewController {
weak var delegate: HomeViewControllerDelegate?
func profileTapped() {
delegate?.homeDidSelectProfile()
}
}Обработка Route
Координатор соответствует delegate и решает, как выполнить навигацию при возникновении события.
extension AppCoordinator: HomeViewControllerDelegate {
func homeDidSelectProfile() {
let profile = ProfileViewController()
navigationController.pushViewController(profile, animated: true)
}
}Дочерние координаторы
Большие потоки (введение в приложение, оформление заказа) получают собственные дочерние координаторы. Родитель запускает дочерний координатор и сохраняет его в childCoordinators, чтобы тот оставался активным.
func startOnboarding() {
let child = OnboardingCoordinator(navigationController: navigationController)
childCoordinators.append(child)
child.start()
}Предотвращение утечек памяти
Поскольку родитель хранит дочерние координаторы, необходимо удалить дочерний координатор, когда его поток завершается, иначе возникнет утечка. Распространённый подход — использовать обратный вызов завершения.
func childDidFinish(_ child: Coordinator) {
childCoordinators.removeAll { $0 === child }
}Координаторы в SwiftUI
В SwiftUI координаторы часто управляют путём NavigationStack. Координатор владеет наблюдаемым путём, а представления добавляют в него маршруты.
final class Router: ObservableObject {
@Published var path: [Route] = []
func push(_ route: Route) {
path.append(route)
}
}
enum Route: Hashable { case profile, settings }Итоги преимуществ
Паттерн координатора даёт Вам:
- Повторно используемые представления, в которых навигация не задана жёстко
- Централизованную логику потока, которую легко изменять
- Маршрутизацию, пригодную для тестирования и отделённую от пользовательского интерфейса
- Комбинируемые потоки с помощью дочерних координаторов
Быстрая проверка
Проверьте, насколько хорошо Вы поняли координаторы.
Итоги
Вы изучили паттерн координатора:
- Координаторы владеют навигацией, поэтому представлениям не нужно знать о маршрутизации
- Представления передают события вверх через delegate или замыкания
- Дочерние координаторы описывают самостоятельные потоки
- После завершения потоков дочерние координаторы удаляются, чтобы избежать утечек
Вместе с MVVM координаторы формируют чистую архитектуру, удобную для тестирования.
Часто задаваемые вопросы
Урок «Шаблон координатора» бесплатный?
Да — полный текст урока «Шаблон координатора» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Swift Academy, подпишись на CoddyKit PRO. Курс Swift Academy содержит 4 уроков всего.
Чему я научусь в уроке «Шаблон координатора»?
Централизуйте логику навигации. Ты практикуешь Swift Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Swift Academy?
Предыдущий опыт не требуется. Swift Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Шаблон координатора»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Swift Academy?
Да. Каждый урок Swift Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Шаблон MVVM
- Связывание моделей представления с представлениями
- Шаблон координатора
- Тестирование моделей представления