-
Notifications
You must be signed in to change notification settings - Fork 318
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Hybrid Router #3261
Hybrid Router #3261
Conversation
bd611ce
to
8a9a26e
Compare
f7d1583
to
994a1de
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding some tests are very much welcomed.
The API is easy to use, thumbs up!
afcefff
to
7e4a4c0
Compare
f258de9
to
369205f
Compare
235eb2c
to
68a07a1
Compare
} | ||
|
||
extension URL { | ||
func removingSKU() -> URL { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing the SKU
token, as NN automatically appends it on their side, which may result in conflict.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have an integration test for this? I'm worried that we break encapsulation here by using magic constant "sku". Can we move this logic to Directions library?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it should be a publicly available Directions feature, as it is a part of internal logic communicating w/ NN. Agreed on magic constants usage, but don't know how to avoid it in this case as ideally it should be shared with Directions too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nave you concidered using SPI? https://github.com/apple/swift/pull/29810
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can it be shared through the environment, the same way we used to share the SKU token with MapboxDirections?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could. It would require internal changes on Directions side too, so maybe we could do it as a tailwork?
5449667
to
b775cdb
Compare
b775cdb
to
b06af4d
Compare
b06af4d
to
8e3ef17
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
No breaking changes detected in MapboxCoreNavigation |
No breaking changes detected in MapboxNavigation |
/** | ||
Use online data only | ||
|
||
In order for such `MapboxRoutingProvider` to function properly, proper navigation data should be available onboard. `.offline` router will not be able to refresh routes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not really clear what "onboard" means. Can we think of a better word that is more widely used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.offline
router will not be able to refresh routes.
Is future tense needed here? >> Offline routing provider can't refresh routes. <Link to what "refresh route" means.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code comment corrected. I don't quite understand the issue with tenses. Is it not grammatical?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is correct, but maybe not that good to use it here.
fileprivate func parseResponse<ResponseType: Codable>(requestId: RequestId, userInfo: [CodingUserInfoKey : Any], result: Expected<AnyObject, AnyObject>, completion: @escaping (Result<ResponseType, DirectionsError>) -> Void) { | ||
do { | ||
let json = result.value as? String | ||
guard let data = json?.data(using: .utf8) else { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Data(json.utf8)
isn't nullable type, so we can guard on emtpy json and proceed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I didn't get your suggestion
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
guard let json = result.value as? String else {...}
let data = Data(json.utf8)
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it preferable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Data(json.utf8)
isn't optional.
data(using: .utf8)
is optional.
It is more clear that this code can fail because result value is of incorrect type. In your variant it is hidden, but the one who knows that data method returns nullable, it is not.
Just noticed, that you could use Result+Expected.swift
for parsing NavNative's Expected type.
No breaking changes detected in MapboxCoreNavigation |
No breaking changes detected in MapboxNavigation |
credentials: settings.directions.credentials) | ||
self.router = RouterFactory.build(for: source.nativeSource, | ||
cache: factory.cacheHandle, | ||
historyRecorder: factory.historyRecorder) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found the following issues with this approach:
NativeHandlersFactory
is created without the potentially adjusted history URL. In the example app, it leads to two alive CacheHandles.- If the above is fixed, there will still be an issue with the Router using a different instance of the history record handler.
I don't think we are supposed to have more than one history recorder unless it is an artificial use case.
So we shall reuse the history recorder from Navigator
and, in the future, decouple HistoryRecorder from Navigator/PassiveLocationProvider/RouteController.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We assume that settings are configured before any call to SDK entities is done. Due to CacheHandlerFactory
CacheHandle
instance should be reused between MapboxRoutingProvider
and Navigator
. But history recorder will be created twice, that's true. Not sure how critical it is, and not sure what's the best way to mitigate this. Referring to Navigator
here is not an option since it will trigger MBNNNavigator
initialization which is not desired.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We assume that settings are configured before any call to SDK entities is done. Due to CacheHandlerFactory CacheHandle instance should be reused between MapboxRoutingProvider and Navigator.
Please try Example app, it doesn't seem to work as you describe.
Referring to Navigator here is not an option since it will trigger MBNNNavigator initialization which is not desired.
Well, then we need similar approach to CacheHandlerFactory. Or change it completely to not only cache cachehandle, but other relevant instances as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, there was a difference in cache key form Routing Provider and Navigator, I think I fixed it by adding more parameters to CacheHandlerFactory initialization. At least it should work if Navigator
's parameters are not modified before launch.
I also added same caching mechanism for HistoryRecorder
. I would prefer to solve this issue in a different way, but I don't know how, and it is outside of this task's scope. Currently, only CacheHandle
and HistoryRecorder
instances are used in multiple places, so I've added caching only for these 2. With HandlerFactory
it should be trivial to add caching to any other required entity though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's resolve this thread, although it is not clear what will happen during switch to offline/online for Navigator.
99e73e7
to
c46cc50
Compare
No breaking changes detected in MapboxCoreNavigation |
No breaking changes detected in MapboxNavigation |
No breaking changes detected in MapboxCoreNavigation |
No breaking changes detected in MapboxNavigation |
…r functionality for requesting and refreshing routes; removed Directions extension and Navigator.routerInterface; added CacheHandlerFactory to cache latest CacheHandle created.
…tingProvider uses the same cache and history recorder handles; refactored handlers caching class to be more generic (+9 squashed commits) Squashed commits: [99e73e7] vk-1024-hybrid-router: improved code comments; added sanity check for route refreshing; re-organized MapboxRoutingProvider.swift [cd1a117] vk-1024-hybrid-router: CHANGELOG updated. [26467b8] vk-1024-hybrid-router: reverted breaking changes; update code to be backwards compatible [6a7833e] vk-1024-hybrid-router: improved code readability; fixed Directions RoutingProvider callbacks calling thread [683b7cd] vk-1024-hybrid-router: restored file references [a77db21] vk-1024-hybrid-router: fixed unit tests; updated deprecated directions symbols usage; NN imports updated [f3dd481] vk-1024-hybrid-router: renamed new entities and it's members; added assertation messages, added code doc for CacheHandlerFactory. [838cd74] vk-1024-hybrid-router: file references added. [2e1ff03] vk-1024-hybrid-router: unit tests updated. CHANGELOG updated. (+5 squashed commits) Squashed commits: [1b2285a] vk-1024-hybrid-router: introduced NavigationProvider protocol to allow usage Directions or NavigationRouter for routing tasks. Corresponding conformances added. [30c02f5] vk-1024-hybrid-router: eased conditions for reporting an error on offline route refreshing attempt [54e287d] vk-1024-hybrid-router: RouteController update route fixed [8e3ef17] vk-1024-hybrid-router: restored NavigationService changes. Tests fixed. [c8937ff] vk-1024-hybrid-router: CHANGELOG updated.
c51f3b4
to
6af4602
Compare
No breaking changes detected in MapboxCoreNavigation |
No breaking changes detected in MapboxNavigation |
No breaking changes detected in MapboxCoreNavigation |
No breaking changes detected in MapboxNavigation |
Description
This PR introduces "Hybrid
TheoryRouter" usage. This feature adds API to allow making explicitly online/offline/hybrid route requests, selecting between Directions or onboard router engine.Implementation
Removed previous
Directions
extension with similar functionality. Tried to make feature similar to Android analog. AddedNavigationRouter
(naming suggestions are welcome) to be responsible for making requests. User is free to instantiate a router for a single request or keep the object alive to make several requests.Current implementation has not finished parsing refreshing response (TODO).