iOS-Koordinatormuster
Lassen Sie uns im heutigen Artikel das Koordinatormuster im Detail untersuchen. Wir werden sehen, wie man einen Koordinator von Grund auf einrichtet und welche Vorteile die Implementierung desselben in iOS-Projekten mit sich bringt
Hintergrund…….
Wie wir alle wissen, sind MVVM und MVC die am häufigsten verwendeten iOS-Designmuster (manchmal könnte es sich um einen riesigen View Controller handeln ). Einer der größten Nachteile dieser Muster besteht darin, dass die Controller die Logik für das Routing enthalten. Hier kann Routing die Initialisierung und Handhabung der nächsten Controller im Geschäftsfluss sein.
Koordinatormuster…….
Das Koordinatormuster überwindet dieses Problem, indem es die Routing-Logik abstrahiert. Hier sind alle View-Controller, die logisch unter einem Business-Flow-Koordinator gruppiert werden können, mit dem Koordinator verknüpft. Der Koordinator trägt die alleinige Verantwortung für den nächsten Controller im Geschäftsablauf. Dadurch wird die Routing-Logik besser lesbar, wartbar und erweiterbar.
Koordinator HLD….
Koordinator im Einsatz…..
Sehen wir uns nun an, wie wir ein Koordinatormuster von Grund auf erstellen können.
Koordinatorprotokoll: Erstellen wir eine Schnittstelle für unsere Koordinatoren, die alle Koordinatoren verpflichtet, sich an unseren Erwartungen zu orientieren.
- navController: Dies wäre der Navigationscontroller zur Verwaltung des Viewcontroller-Stacks.
- eventOccurred(T): Dies würde von unseren Viewcontrollern verwendet werden, um den Koordinator über jedes Navigationsereignis zu informieren
- start(): Diese einmalige Methode wird aufgerufen, um den Geschäftsablauf zu starten
protocol Coordinator {
var navController : UINavigationController? { get set }
func eventOccurred<T: RawRepresentable>(type: T) where T.RawValue == Int
func start()
}
protocol Coordinating {
var coordinator: Coordinator? { get set}
}
typealias CoordinatingVC = UIViewController & Coordinating
class ViewController: CoordinatingVC {
var coordinator: Coordinator?
override func viewDidLoad() {
super.viewDidLoad()
setUp()
setUpCTA()
}
private func setUp() {
self.view.backgroundColor = .white
self.title = "Screen1"
}
private func setUpCTA() {
let screen2CTA = UIButton()
screen2CTA.setTitle("Go to Screen2", for: .normal)
screen2CTA.backgroundColor = .gray
view.addSubview(screen2CTA)
screen2CTA.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
screen2CTA.leadingAnchor.constraint(equalTo: view.leadingAnchor,
constant: AppUIConfig.padding),
screen2CTA.trailingAnchor.constraint(equalTo: view.trailingAnchor,
constant: -AppUIConfig.padding),
screen2CTA.centerYAnchor.constraint(equalTo: view.centerYAnchor),
screen2CTA.heightAnchor.constraint(equalToConstant: AppUIConfig.buttonheight)
])
screen2CTA.addTarget(self,
action: #selector(screen2CTATapped),
for: .touchUpInside)
}
@objc func screen2CTATapped() {
coordinator?.eventOccurred(type: MainCoordinatorEvent.screen2)
}
}
enum MainCoordinatorEvent: Int {
case screen2
case screen1
}
class MainCoordinator : Coordinator {
func eventOccurred<T>(type: T) where T : RawRepresentable, T.RawValue == Int {
guard let type = type as? MainCoordinatorEvent else {
return
}
switch type {
case .screen2:
setupScreen2()
case .screen1:
setupScreen1()
}
}
var navController: UINavigationController?
func start() {
setupScreen1()
}
private func setupScreen1() {
guard var navController = navController else {
return
}
if let firstVC = navController.viewControllers.first {
navController.popToViewController(firstVC, animated: true)
return
}
var viewController: CoordinatingVC = ViewController()
viewController.coordinator = self
navController.setViewControllers([viewController], animated: false)
}
private func setupScreen2() {
var viewController: CoordinatingVC = ViewController2()
viewController.coordinator = self
navController?.pushViewController(viewController, animated: true)
}
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
setUpWindow()
return true
}
private func setUpWindow() {
let window = createKeyWindow()
let mainCoordinator = createMainCoordinator()
window.rootViewController = mainCoordinator.navController
window.makeKeyAndVisible()
self.window = window
mainCoordinator.start()
}
private func createMainCoordinator() -> Coordinator {
let navViewController = UINavigationController()
let mainCoordinator = MainCoordinator()
mainCoordinator.navController = navViewController
return mainCoordinator
}
private func createKeyWindow() -> UIWindow {
let window = UIWindow(frame: UIScreen.main.bounds)
return window
}
Jetzt wissen wir, wie man einen Geschäftsfluss mithilfe des Koordinatormusters verwaltet. Wir können das Muster rekursiv erweitern , um Gruppen von Koordinatoren zu verwalten und so die Verwaltung jedes logisch gruppierten Benutzerflusses für sich zu vereinfachen.
Das Befolgen des Koordinatormusters in iOS-Apps macht das Routing zwischen Benutzerflüssen sauberer und robuster. Dadurch ist jeder View-Controller wirklich isoliert und einfach zu warten.
Verweise :
https://www.hackingwithswift.com/articles/71/how-to-use-the-coordinator-pattern-in-ios-apps
https://www.youtube.com/watch?v=SAZzcKvOvAE

![Was ist überhaupt eine verknüpfte Liste? [Teil 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)



































