Pārlūkot izejas kodu

First time routing to products through the coordinators chain logic implemented

Pavel Yurchenko 1 gadu atpakaļ
vecāks
revīzija
71da109b1a

+ 5 - 1
CoordinatorSUI/Sources/CoordinatorSUI/BaseCoordinator.swift

@@ -15,6 +15,10 @@ open class BaseCoordinator: Coordinator {
 
     public var currentRouter: Router = Router()
 
+    public var currentCoordinator: Coordinator? {
+        childCoordinators.last
+    }
+
     // MARK: - Private properties
 
     private var childCoordinators = [Coordinator]()
@@ -34,7 +38,7 @@ open class BaseCoordinator: Coordinator {
 
     public init() { }
 
-    open func run() {}
+    open func run() -> any View { EmptyView() }
 
     deinit {
         print("\(self.self) deinit")

+ 8 - 2
CoordinatorSUI/Sources/CoordinatorSUI/Coordinator.swift

@@ -5,10 +5,16 @@
 //  Created by Pavel Yurchenko on 28.11.2024.
 //
 
-import Foundation
+import SwiftUI
 
 public protocol Coordinator: AnyObject {
     var finishFlow: Action? { get set }
     var currentRouter: Router { get }
-    func run()
+}
+
+public extension Coordinator {
+    @ViewBuilder
+    func run() -> some View {
+        EmptyView()
+    }
 }

+ 2 - 2
CoordinatorSUI/Sources/CoordinatorSUI/Router.swift

@@ -16,11 +16,11 @@ public final class Router: ObservableObject {
 
     }
 
-    func push(_ route: any Hashable) {
+    public func push(_ route: any Hashable) {
         path.append(route)
     }
 
-    func pop() {
+    public func pop() {
         path.removeLast()
     }
 }

+ 11 - 3
SUIExamples/Application/ApplicationCoordinator.swift

@@ -6,6 +6,7 @@
 //
 
 import CoordinatorSUI
+import SwiftUI
 
 final class ApplicationCoordinator: BaseCoordinator {
 
@@ -16,19 +17,26 @@ final class ApplicationCoordinator: BaseCoordinator {
         self.currentRouter = Self.rootRouter
     }
 
-    override func run() {
+    func run() -> some View {
         runMainFlow()
     }
 
+    func buildDestination(_ route: Route) -> some View {
+        guard let coordinator = currentCoordinator as? MainCoordinator else {
+            fatalError("Invalid coordinator type")
+        }
+        return coordinator.buildDestination(route)
+    }
+
     // MARK: - Private methods
 
-    private func runMainFlow() {
+    private func runMainFlow() -> some View {
         let coordinator = MainCoordinator(router: self.currentRouter)
         addChild(coordinator)
         coordinator.finishFlow = { [weak self] in
             self?.removeChild(coordinator)
         }
-        coordinator.run()
+        return coordinator.run()
     }
 }
 

+ 1 - 8
SUIExamples/Application/SUIExamplesApp.swift

@@ -17,14 +17,7 @@ struct SUIExamplesApp: App {
     var body: some Scene {
         WindowGroup {
             NavigationStack(path: $router.path) {
-                MainBuilder().build(
-                    with: .init(
-                        onProducts: {
-                            router.path.append(
-                                Route.products
-                            )
-                        })
-                )
+                applicationCoordinator.run()
                 .navigationDestination(
                     for: Route.self,
                     destination: applicationCoordinator.buildDestination

+ 25 - 1
SUIExamples/Flows/MainCoordinator.swift

@@ -6,6 +6,7 @@
 //
 
 import CoordinatorSUI
+import SwiftUI
 
 final class MainCoordinator: BaseCoordinator {
 
@@ -14,8 +15,31 @@ final class MainCoordinator: BaseCoordinator {
         self.currentRouter = router
     }
 
-    override func run() {
+    func run() -> some View {
+        showMainModule()
+    }
 
+    @ViewBuilder
+    func buildDestination(_ route: Route) -> some View {
+        switch route {
+        case .products:
+            showProductsModule()
+        default: EmptyView()
+        }
     }
 
+    // MARK: - Private methods
+
+    private func showMainModule() -> some View {
+        MainBuilder().build(
+            with: .init(
+                onProducts: { [weak self] in
+                    self?.currentRouter.push(Route.products)
+                })
+        )
+    }
+
+    private func showProductsModule() -> some View {
+        ProductsBuilder().build(with: .init())
+    }
 }