Skip to content

Commit e3c00a9

Browse files
committed
refactor: update router naming
1 parent d032cc4 commit e3c00a9

File tree

11 files changed

+228
-228
lines changed

11 files changed

+228
-228
lines changed

Giffy/App/MainApp.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import netfox
1212

1313
@main
1414
struct MainApp: App {
15-
@Route var router
15+
@Router var router
1616

1717
init() {
1818
Font.loadCustomFont()

Giffy/App/Router/Route.swift

Lines changed: 0 additions & 45 deletions
This file was deleted.

Giffy/App/Router/RouteView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import CommonUI
1313

1414
struct RouteView: View {
1515
let store: StoreOf<RouteReducer>
16-
@Route var router
16+
@Router var router
1717

1818
var body: some View {
1919
WithViewStore(store, observe: { $0 }) { viewStore in

Giffy/App/Router/Router.swift

Lines changed: 30 additions & 175 deletions
Original file line numberDiff line numberDiff line change
@@ -1,190 +1,45 @@
11
//
2-
// Router.swift
2+
// AppRoute.swift
33
// GiphyGIF
44
//
55
// Created by Uwais Alqadri on 10/10/24.
66
//
77

88
import Foundation
9-
import SwiftUI
10-
11-
public protocol RouterIdentifiable: Equatable {
12-
var key: String { get }
13-
}
14-
15-
public final class Router<T: RouterIdentifiable> {
16-
private var routes: [T] = []
17-
public var onMakeRoot: ((T, Bool) -> Void)?
18-
public var onPush: ((T, Bool) -> Void)?
19-
public var onPresent: ((T, Bool) -> Void)?
20-
public var onPopLast: ((Int, Bool) -> Void)?
21-
public var onPopToRoot: ((Int?, Bool) -> Void)?
22-
23-
public var currentRoutes: [T] {
24-
return routes
25-
}
26-
27-
public init(initial: T? = nil) {
28-
if let initial = initial { push(initial) }
29-
}
30-
31-
public func makeRoot(_ route: T, animated: Bool = true, needValidate: Bool = false) {
32-
guard !(needValidate && routes.last?.key == route.key) else { return }
33-
routes = [route]
34-
onMakeRoot?(route, animated)
35-
}
36-
37-
public func push(_ route: T, animated: Bool = true, needValidate: Bool = false) {
38-
guard !(needValidate && routes.last?.key == route.key) else { return }
39-
routes.append(route)
40-
onPush?(route, animated)
41-
}
42-
43-
public func present(_ route: T, animated: Bool = true, needValidate: Bool = false) {
44-
guard !(needValidate && routes.last?.key == route.key) else { return }
45-
routes.append(route)
46-
onPresent?(route, animated)
47-
}
48-
49-
public func pop(animated: Bool = true) {
50-
guard !routes.isEmpty else { return }
51-
let popped = routes.removeLast()
52-
print("Router popped: \(popped)")
53-
onPopLast?(1, animated)
54-
}
55-
56-
public func popTo(last index: Int, animated: Bool = true) {
57-
guard !routes.isEmpty else { return }
58-
let elementsToRemove = min(index - 1, routes.count - 1)
59-
routes.removeLast(elementsToRemove)
60-
onPopLast?(index, animated)
61-
}
62-
63-
public func popTo(_ route: T, inclusive: Bool = false, animated: Bool = true) {
64-
guard let foundIndex = routes.lastIndex(where: { $0 == route }) else { return }
65-
let indexToPopTo = inclusive ? foundIndex : foundIndex + 1
66-
guard indexToPopTo != 0 else {
67-
popToRoot(index: nil, animated: animated)
68-
return
69-
}
70-
71-
let numToPop = routes.count - indexToPopTo
72-
routes.removeLast(numToPop)
73-
onPopLast?(numToPop, animated)
74-
}
75-
76-
public func popToRoot(index: Int? = nil, animated: Bool = true) {
77-
onPopToRoot?(index, animated)
78-
if routes.count > 1 {
79-
routes.removeSubrange(1 ..< routes.count)
80-
}
81-
}
82-
83-
public func onSystemPop() {
84-
guard !routes.isEmpty else { return }
85-
let popped = routes.removeLast()
86-
print("Router popped: \(popped)")
87-
}
88-
}
89-
90-
public struct RouteProvider<T: RouterIdentifiable, Screen: View>: View {
91-
private let router: Router<T>
92-
@ViewBuilder private let routeMap: (T) -> Screen
93-
94-
public init(_ router: Router<T>, @ViewBuilder _ routeMap: @escaping (T) -> Screen) {
95-
self.router = router
96-
self.routeMap = routeMap
97-
}
98-
99-
public var body: some View {
100-
NavigationControllerHost(router: router, routeMap: routeMap)
101-
.edgesIgnoringSafeArea(.all)
102-
}
103-
}
104-
105-
struct NavigationControllerHost<T: RouterIdentifiable, Screen: View>: UIViewControllerRepresentable {
106-
let router: Router<T>
107-
@ViewBuilder var routeMap: (T) -> Screen
108-
109-
func makeUIViewController(context: Context) -> PopAwareUINavigationController {
110-
let navigation = PopAwareUINavigationController()
111-
navigation.navigationBar.isHidden = true
112-
setupRouterCallbacks(in: navigation)
113-
setupInitialRoutes(in: navigation)
114-
return navigation
115-
}
116-
117-
private func setupRouterCallbacks(in navigation: PopAwareUINavigationController) {
118-
navigation.popHandler = { router.onSystemPop() }
119-
navigation.stackSizeProvider = { router.currentRoutes.count }
120-
121-
router.onMakeRoot = { route, animated in
122-
let viewController = UIHostingController(rootView: routeMap(route))
123-
navigation.setViewControllers([viewController], animated: animated)
124-
}
125-
126-
router.onPush = { route, animated in
127-
let viewController = UIHostingController(rootView: routeMap(route))
128-
navigation.pushViewController(viewController, animated: animated)
129-
}
130-
131-
router.onPresent = { route, animated in
132-
let viewController = UIHostingController(rootView: routeMap(route))
133-
viewController.modalPresentationStyle = .overFullScreen
134-
navigation.present(viewController, animated: animated)
135-
}
136-
137-
router.onPopLast = { numToPop, animated in
138-
let popTo = navigation.viewControllers.count - numToPop - 1
139-
if numToPop == navigation.viewControllers.count {
140-
navigation.viewControllers = []
141-
} else {
142-
navigation.popToViewController(navigation.viewControllers[popTo], animated: animated)
143-
}
144-
}
145-
146-
router.onPopToRoot = { tabIndex, animated in
147-
navigation.popToRootViewController(animated: animated)
148-
if let tabIndex = tabIndex {
149-
NotificationCenter.default.post(
150-
name: NSNotification.Name("shouldOpenTab"),
151-
object: nil,
152-
userInfo: ["tabIndex": tabIndex]
153-
)
154-
}
155-
}
156-
}
157-
158-
private func setupInitialRoutes(in navigation: PopAwareUINavigationController) {
159-
for path in router.currentRoutes {
160-
navigation.pushViewController(UIHostingController(rootView: routeMap(path)), animated: true)
9+
import Common
10+
11+
public enum AppRoute: RouterIdentifiable {
12+
case main
13+
case home
14+
case search
15+
case favorite
16+
case detail(items: [Giffy])
17+
18+
public var key: String {
19+
switch self {
20+
case .main:
21+
return "main"
22+
case .home:
23+
return "main"
24+
case .search:
25+
return "search"
26+
case .favorite:
27+
return "favorite"
28+
case .detail:
29+
return "detail"
16130
}
16231
}
163-
164-
func updateUIViewController(_ navigation: PopAwareUINavigationController, context: Context) {
165-
navigation.navigationBar.isHidden = true
166-
}
167-
168-
static func dismantleUIViewController(_ navigation: PopAwareUINavigationController, coordinator: ()) {
169-
navigation.viewControllers = []
170-
navigation.popHandler = nil
171-
}
172-
173-
typealias UIViewControllerType = PopAwareUINavigationController
17432
}
17533

176-
class PopAwareUINavigationController: UINavigationController, UINavigationControllerDelegate {
177-
var popHandler: (() -> Void)?
178-
var stackSizeProvider: (() -> Int)?
34+
@propertyWrapper
35+
public struct Router {
36+
public init() {}
17937

180-
override func viewDidLoad() {
181-
super.viewDidLoad()
182-
delegate = self
183-
}
38+
private var customValue: Routing<AppRoute>?
39+
public static var defaultRouter: Routing<AppRoute> = Routing()
18440

185-
func navigationController(_ navigationController: UINavigationController, didShow _: UIViewController, animated _: Bool) {
186-
if let stackSizeProvider = stackSizeProvider, stackSizeProvider() > navigationController.viewControllers.count {
187-
popHandler?()
188-
}
41+
public var wrappedValue: Routing<AppRoute> {
42+
get { customValue ?? Self.defaultRouter }
43+
set { customValue = newValue }
18944
}
19045
}

0 commit comments

Comments
 (0)