Я экспериментирую с маршрутизацией в приложении iOS.
Мой текущий подход натолкнулся на препятствие, однако я создаю ViewControllerFactory
и NavigationControllerRouter
.
Задача, с которой я столкнулся, заключается в том, что ViewControllerFactory
необходимо указать маршрутизатору, какой маршрут требуется затем, а NavigationControllerRouter
требует, чтобы фабрика передала контроллер представления в контроллер навигации.
Как могут эти 2 компонента общаться без создания сильной связи?
enum Route {
case login
case home
}
protocol ViewControllerFactory {
func create(for route: Route) -> UIViewController
}
class VCFactory: ViewControllerFactory {
func create(for route: Route) -> UIViewController {
switch route {
case .login:
let viewController = UIViewController()
viewController.view.backgroundColor = .purple
return viewController
case .home:
let viewController = UIViewController()
viewController.view.backgroundColor = .red
return viewController
}
}
}
class NavigationControllerRouter {
private let navigationController: UINavigationController
private let factory: ViewControllerFactory
init(_ navigationController: UINavigationController, factory: ViewControllerFactory) {
self.navigationController = navigationController
self.factory = factory
}
func route(to route: Route) {
let viewController = factory.create(for: route)
navigationController.pushViewController(viewController, animated: true)
}
}
Я настроил это следующим образом
@available(iOS 13.0, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
private lazy var navController = UINavigationController()
private lazy var router: NavigationControllerRouter = {
let viewControllerFactory = VCFactory()
return NavigationControllerRouter(navController, factory: viewControllerFactory)
}()
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let scene = (scene as? UIWindowScene) else { return }
let window = UIWindow(windowScene: scene)
configure(window)
}
func configure(_ window: UIWindow) {
self.window = window
self.window?.makeKeyAndVisible()
self.window?.rootViewController = navController
router.route(to: .login)
}
}
Я рассмотрел передачу слабой ссылки для маршрутизатора на фабрику контроллера представления, а затем внедрил это в любые визуализированные представления, однако это затем объединяет 2, особенно если я решу использовать фабрику представлений для чего-то вроде дочерних представлений, которые вообще не должны знать о маршрутизаторе.