I implemented this pattern based on the video Why You Should Use The SwiftUI Coordinator Pattern
Everything worked out but there was a problem with loading data several times.
import SwiftUI
protocol IShowJobPageSceneDelegate: AnyObject {
func showJobPageScene(id: String)
}
protocol IShowPasswordSceneDelegate: AnyObject {
func showPasswordScene(eMail: String)
}
protocol IShowSearchSceneDelegate: AnyObject {
func showSearchScene()
}
protocol IBackSceneDelegate: AnyObject {
func backScene()
}
enum Flow: Hashable {
case loginScene
case passwordScene(String)
case vacancyScene
case jobScene(String)
}
final class SearchCoordinator: ObservableObject {
@Published var flow: Flow = .loginScene
@Published var path: NavigationPath = NavigationPath()
func push(_ page: Flow) {
path.append(page)
}
func pop() {
path.removeLast()
}
func popToRoot() {
path.removeLast(path.count)
}
@ViewBuilder
func changeFlow(flow: Flow, globalFavoritesModel: GlobalFavoritesModel) -> some View {
switch (flow, globalFavoritesModel.isAuthorized) {
case (.loginScene, false):
let assembler = AssemblerLoginView()
assembler.configurator(delegate: self)
case (.passwordScene(let email), _):
let assembler = AssemblerPasswordView()
assembler.configurator(delegate: self, modelDTO: email)
case (.vacancyScene, _):
let assembler = AssemblerMainSearch()
assembler.configurator(delegate: self, globalModel: globalFavoritesModel)
case (.jobScene(let vacancyID), _):
let assembler = AssemblerJobPage()
assembler.configurator(backSceneDelegate: self, modelDTO: vacancyID)
case (_, true):
let assembler = AssemblerMainSearch()
assembler.configurator(delegate: self, globalModel: globalFavoritesModel)
}
}
}
extension SearchCoordinator: IShowJobPageSceneDelegate {
func showJobPageScene(id: String) {
self.push(.jobScene(id))
}
}
extension SearchCoordinator: IBackSceneDelegate {
func backScene() {
self.pop()
}
}
extension SearchCoordinator: IShowPasswordSceneDelegate {
func showPasswordScene(eMail: String) {
self.push(.passwordScene(eMail))
}
}
extension SearchCoordinator: IShowSearchSceneDelegate {
func showSearchScene() {
push(.vacancyScene)
}
}
The problem in the navigation stack repeats several times
NavigationStack(path: self.$coordinator.path) {
}
import SwiftUI
struct SearchCoordinatorView: View {
@StateObject private var coordinator = SearchCoordinator()
@EnvironmentObject var globalFavoritesModel: GlobalFavoritesModel
var body: some View {
NavigationStack(path: self.$coordinator.path) {
self.coordinator.changeFlow(flow: coordinator.flow, globalFavoritesModel: globalFavoritesModel)
.navigationDestination(for: Flow.self) { page in
self.coordinator.changeFlow(flow: page, globalFavoritesModel: globalFavoritesModel)
.navigationBarTitle("", displayMode: .inline)
.navigationBarBackButtonHidden(true)
}
}
}
}