Skip to content

Commit ff7e5f9

Browse files
Minor refactoring
* Minor refactoring * Update version Co-authored-by: amisha <amisha.i@canopas.com>
1 parent 9c2cb59 commit ff7e5f9

File tree

4 files changed

+54
-65
lines changed

4 files changed

+54
-65
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ Once you have your Swift package set up, adding UIPilot as a dependency is as ea
3838

3939
```swift
4040
dependencies: [
41-
.package(url: "https://github.com/canopas/UIPilot.git", .upToNextMajor(from: "1.3.0"))
41+
.package(url: "https://github.com/canopas/UIPilot.git", .upToNextMajor(from: "1.3.1"))
4242
]
4343
```
4444

@@ -47,7 +47,7 @@ dependencies: [
4747
[CocoaPods][] is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate UIPilot into your Xcode project using CocoaPods, specify it in your Podfile:
4848

4949
target 'YourAppName' do
50-
pod 'UIPilot', '~> 1.3.0'
50+
pod 'UIPilot', '~> 1.3.1'
5151
end
5252

5353
[CocoaPods]: https://cocoapods.org

Sources/UIPilot/UIPilot.swift

Lines changed: 49 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ import Combine
44
public class UIPilot<T: Equatable>: ObservableObject {
55

66
private let logger: Logger
7-
private let viewGenerator = PathViewGenerator<T>()
8-
7+
98
@Published var paths: [UIPilotPath<T>] = []
109

1110
public var stack: [T] {
@@ -16,13 +15,6 @@ public class UIPilot<T: Equatable>: ObservableObject {
1615
logger = debug ? DebugLog() : EmptyLog()
1716
logger.log("UIPilot - Pilot Initialized.")
1817

19-
viewGenerator.onPop = { [weak self] path in
20-
if let self = self, self.paths.count > 1
21-
&& path.id == self.paths[self.paths.count - 2].id {
22-
self.pop()
23-
}
24-
}
25-
2618
push(initial)
2719
}
2820

@@ -59,10 +51,14 @@ public class UIPilot<T: Equatable>: ObservableObject {
5951
logger.log("UIPilot - Popping \(numToPop) routes")
6052
paths.removeLast(numToPop)
6153
}
62-
63-
func getView<Screen: View>(_ paths: [UIPilotPath<T>], _ routeMap: RouteMap<T, Screen>, _ pathViews: [UIPilotPath<T>: Screen]) -> (PathView<Screen>?, [UIPilotPath<T>: Screen]) {
64-
return viewGenerator.generate(paths, routeMap, pathViews)
54+
55+
func systemPop(path: UIPilotPath<T>) {
56+
if paths.count > 1
57+
&& path.id == self.paths[self.paths.count - 2].id {
58+
self.pop()
59+
}
6560
}
61+
6662
}
6763

6864
struct UIPilotPath<T: Equatable>: Equatable, Hashable {
@@ -125,22 +121,51 @@ class PathViewState<Screen: View>: ObservableObject {
125121
}
126122
}
127123

128-
class PathViewGenerator<T: Equatable> {
124+
public struct UIPilotHost<T: Equatable, Screen: View>: View {
125+
126+
@ObservedObject
127+
private var pilot: UIPilot<T>
128+
@ViewBuilder
129+
private let routeMap: (T) -> Screen
130+
131+
@State
132+
private var viewGenerator = ViewGenerator<T, Screen>()
133+
134+
public init(_ pilot: UIPilot<T>, @ViewBuilder _ routeMap: @escaping (T) -> Screen) {
135+
self.pilot = pilot
136+
self.routeMap = routeMap
137+
self.viewGenerator.onPop = { path in
138+
pilot.systemPop(path: path)
139+
}
140+
}
141+
142+
public var body: some View {
143+
NavigationView {
144+
viewGenerator.build(pilot.paths, routeMap)
145+
}
146+
#if !os(macOS)
147+
.navigationViewStyle(.stack)
148+
#endif
149+
.environmentObject(pilot)
150+
}
151+
}
129152

130-
var onPop: ((UIPilotPath<T>) -> Void)?
153+
class ViewGenerator<T: Equatable, Screen: View>: ObservableObject {
154+
var onPop: ((UIPilotPath<T>) -> Void)? = nil
155+
156+
private var pathViews = [UIPilotPath<T>: Screen]()
131157

132-
func generate<Screen: View>(
158+
func build(
133159
_ paths: [UIPilotPath<T>],
134-
@ViewBuilder _ routeMap: RouteMap<T, Screen>,
135-
_ pathViews: [UIPilotPath<T>: Screen]) -> (PathView<Screen>?,
136-
[UIPilotPath<T>: Screen]) {
137-
var pathViews = recycleViews(paths, pathViews: pathViews)
160+
@ViewBuilder _ routeMap: (T) -> Screen) -> PathView<Screen>? {
161+
162+
recycleViews(paths)
138163

139164
var current: PathView<Screen>?
140165
for path in paths.reversed() {
141166
let view = pathViews[path] ?? routeMap(path.route)
142167
pathViews[path] = view
143-
168+
144169
let content = PathView(view, state: PathViewState())
145170

146171
content.state.next = current
@@ -151,53 +176,17 @@ class PathViewGenerator<T: Equatable> {
151176
}
152177
current = content
153178
}
154-
return (current, pathViews)
179+
return current
155180
}
156181

157-
private func recycleViews<Screen: View>(_ paths: [UIPilotPath<T>], pathViews: [UIPilotPath<T>: Screen]) -> [UIPilotPath<T>: Screen] {
158-
var pathViews = pathViews
182+
private func recycleViews(_ paths: [UIPilotPath<T>]){
183+
var pathViews = self.pathViews
159184
for key in pathViews.keys {
160185
if !paths.contains(key) {
161186
pathViews.removeValue(forKey: key)
162187
}
163188
}
164-
return pathViews
165-
}
166-
}
167-
168-
public typealias RouteMap<T, Screen> = (T) -> Screen
169-
170-
public struct UIPilotHost<T: Equatable, Screen: View>: View {
171-
172-
@ObservedObject
173-
private var pilot: UIPilot<T>
174-
175-
@ViewBuilder
176-
let routeMap: RouteMap<T, Screen>
177-
178-
@State
179-
var pathViews = [UIPilotPath<T>: Screen]()
180-
@State
181-
var content: PathView<Screen>?
182-
183-
public init(_ pilot: UIPilot<T>, @ViewBuilder _ routeMap: @escaping RouteMap<T, Screen>) {
184-
self.pilot = pilot
185-
self.routeMap = routeMap
186-
}
187-
188-
public var body: some View {
189-
NavigationView {
190-
content
191-
}
192-
#if !os(macOS)
193-
.navigationViewStyle(.stack)
194-
#endif
195-
.environmentObject(pilot)
196-
.onReceive(pilot.$paths) { paths in
197-
let (newContent, newPathViews) = pilot.getView(paths, routeMap, pathViews)
198-
self.content = newContent
199-
self.pathViews = newPathViews
200-
}
189+
self.pathViews = pathViews
201190
}
202191
}
203192

UIPilot.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Pod::Spec.new do |s|
22
s.name = "UIPilot"
3-
s.version = "1.3.0"
3+
s.version = "1.3.1"
44
s.summary = "The missing type-safe, SwiftUI navigation library."
55

66
s.description = <<-DESC

docs/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ Once you have your Swift package set up, adding UIPilot as a dependency is as ea
317317

318318
```swift
319319
dependencies: [
320-
.package(url: "https://github.com/canopas/UIPilot.git", .upToNextMajor(from: "1.3.0"))
320+
.package(url: "https://github.com/canopas/UIPilot.git", .upToNextMajor(from: "1.3.1"))
321321
]
322322
```
323323

@@ -326,7 +326,7 @@ dependencies: [
326326
[CocoaPods][] is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate UIPilot into your Xcode project using CocoaPods, specify it in your Podfile:
327327

328328
target 'YourAppName' do
329-
pod 'UIPilot', '~> 1.3.0'
329+
pod 'UIPilot', '~> 1.3.1'
330330
end
331331

332332
[CocoaPods]: https://cocoapods.org

0 commit comments

Comments
 (0)