@@ -35,9 +35,10 @@ public class NavigationRouter {
35
35
}
36
36
37
37
public private( set) var activeRequests : [ RequestId : RoutingRequest ] = [ : ]
38
- public private( set) var source : RouterSource
39
- private var router : RouterInterface
40
- private var settings : NavigationSettings
38
+ private let requestsLock = NSLock ( )
39
+ public let source : RouterSource
40
+ private let router : RouterInterface
41
+ private let settings : NavigationSettings
41
42
42
43
public init ( _ source: RouterSource = . hybrid, settings: NavigationSettings = . shared) {
43
44
self . source = source
@@ -55,15 +56,28 @@ public class NavigationRouter {
55
56
}
56
57
57
58
fileprivate func finish( request id: RequestId ) {
59
+ requestsLock. lock ( ) ; defer {
60
+ requestsLock. unlock ( )
61
+ }
62
+
58
63
router. cancelRequest ( forToken: id)
59
64
activeRequests [ id] = nil
60
65
print ( " >>> finished id: \( id) " )
61
66
}
62
67
68
+ func complete( requestId: RequestId , with result: @escaping ( ) -> Void ) {
69
+ DispatchQueue . main. async {
70
+ result ( )
71
+ self . finish ( request: requestId)
72
+ }
73
+ }
74
+
75
+
63
76
public func doRequest< ResponseType: Codable > ( options: DirectionsOptions ,
64
77
completion: @escaping ( Result < ResponseType , DirectionsError > ) -> Void ) -> RequestId {
65
78
let directionsUri = settings. directions. url ( forCalculating: options) . absoluteString
66
79
var requestId : RequestId !
80
+ requestsLock. lock ( )
67
81
requestId = router. getRouteForDirectionsUri ( directionsUri) { [ weak self] ( result, _) in // mind exposing response origin?
68
82
guard let self = self else { return }
69
83
@@ -75,22 +89,21 @@ public class NavigationRouter {
75
89
76
90
if let jsonData = data,
77
91
let response = try ? decoder. decode ( ResponseType . self, from: jsonData) {
78
- DispatchQueue . main . async {
92
+ self . complete ( requestId : requestId ) {
79
93
completion ( . success( response) )
80
- self . finish ( request: requestId)
81
94
}
82
95
} else {
83
- DispatchQueue . main . async {
96
+ self . complete ( requestId : requestId ) {
84
97
completion ( . failure( . unknown( response: nil ,
85
98
underlying: result. error as? Error ,
86
99
code: nil ,
87
100
message: nil ) ) )
88
- self . finish ( request: requestId)
89
101
}
90
102
}
91
103
}
92
104
activeRequests [ requestId] = . init( id: requestId,
93
105
router: self )
106
+ requestsLock. unlock ( )
94
107
print ( " >>> started id: \( requestId) " )
95
108
return requestId
96
109
}
@@ -116,9 +129,8 @@ public class NavigationRouter {
116
129
117
130
@discardableResult public func refreshRoute( indexedRouteResponse: IndexedRouteResponse ,
118
131
fromLegAtIndex startLegIndex: UInt32 = 0 ,
119
- completionHandler: @escaping Directions . RouteRefreshCompletionHandler ) -> RequestId {
132
+ completionHandler: @escaping Directions . RouteCompletionHandler ) -> RequestId {
120
133
guard case let . route( routeOptions) = indexedRouteResponse. routeResponse. options,
121
- let route = indexedRouteResponse. selectedRoute,
122
134
let responseIdentifier = indexedRouteResponse. routeResponse. identifier else {
123
135
preconditionFailure ( " Invalid route data passed for refreshing. " )
124
136
}
@@ -128,52 +140,73 @@ public class NavigationRouter {
128
140
129
141
let routeIndex = UInt32 ( indexedRouteResponse. routeIndex)
130
142
131
- guard let routeData = try ? encoder. encode ( route) ,
143
+ guard
144
+ let routeData = try ? encoder. encode ( indexedRouteResponse. routeResponse) ,
132
145
let routeJSONString = String ( data: routeData, encoding: . utf8) else {
133
146
preconditionFailure ( " Could not serialize route data for refreshing. " )
134
147
}
135
148
136
149
var requestId : RequestId !
137
- requestId = router. getRouteRefresh ( for: RouteRefreshOptions ( requestId: responseIdentifier,
138
- routeIndex: routeIndex,
139
- legIndex: startLegIndex) ,
150
+ let refreshOptions = RouteRefreshOptions ( requestId: responseIdentifier,
151
+ routeIndex: routeIndex,
152
+ legIndex: startLegIndex,
153
+ routingProfile: routeOptions. profileIdentifier. nativeProfile)
154
+ requestsLock. lock ( )
155
+ requestId = router. getRouteRefresh ( for: refreshOptions,
140
156
route: routeJSONString) { [ weak self] result, _ in
141
157
guard let self = self else { return }
142
158
// change to route deserialization
143
159
do {
144
160
let json = result. value as? String
145
161
guard let data = json? . data ( using: . utf8) else {
146
- DispatchQueue . main. async {
147
- completionHandler ( self . settings. directions. credentials, . failure( . noData) )
148
- self . finish ( request: requestId)
162
+ self . complete ( requestId: requestId) {
163
+ let session = ( options: routeOptions as DirectionsOptions ,
164
+ credentials: self . settings. directions. credentials)
165
+ completionHandler ( session, . failure( . noData) )
149
166
}
150
167
return
151
168
}
152
169
let decoder = JSONDecoder ( )
153
- decoder. userInfo = [
154
- . responseIdentifier: responseIdentifier,
155
- . routeIndex: routeIndex,
156
- . startLegIndex: startLegIndex,
157
- . credentials: self . settings. directions. credentials,
158
- ]
170
+ decoder. userInfo = [ . options: routeOptions,
171
+ . credentials: self . settings. directions. credentials]
159
172
160
- let result = try decoder. decode ( RouteRefreshResponse . self, from: data)
173
+ let result = try decoder. decode ( RouteResponse . self, from: data)
161
174
162
- DispatchQueue . main. async {
163
- completionHandler ( self . settings. directions. credentials, . success( result) )
164
- self . finish ( request: requestId)
175
+ self . complete ( requestId: requestId) {
176
+ let session = ( options: routeOptions as DirectionsOptions ,
177
+ credentials: self . settings. directions. credentials)
178
+ completionHandler ( session, . success( result) )
165
179
}
166
180
} catch {
167
- DispatchQueue . main. async {
181
+ self . complete ( requestId: requestId) {
182
+ let session = ( options: routeOptions as DirectionsOptions ,
183
+ credentials: self . settings. directions. credentials)
168
184
let bailError = DirectionsError ( code: nil , message: nil , response: nil , underlyingError: error)
169
- completionHandler ( self . settings. directions. credentials, . failure( bailError) )
170
- self . finish ( request: requestId)
185
+ completionHandler ( session, . failure( bailError) )
171
186
}
172
187
}
173
188
}
174
189
activeRequests [ requestId] = . init( id: requestId,
175
190
router: self )
191
+ requestsLock. unlock ( )
176
192
print ( " >>> started refresh id: \( requestId) " )
177
193
return requestId
178
194
}
179
195
}
196
+
197
+ extension DirectionsProfileIdentifier {
198
+ var nativeProfile : RoutingProfile {
199
+ switch self {
200
+ case . automobile:
201
+ return . driving
202
+ case . automobileAvoidingTraffic:
203
+ return . drivingTraffic
204
+ case . cycling:
205
+ return . cycling
206
+ case . walking:
207
+ return . walking
208
+ default :
209
+ return . driving
210
+ }
211
+ }
212
+ }
0 commit comments