Make InstructionsCardViewController reusable independently of NavigationComponent#2296
Conversation
…. Also reexpose the Route JSON for use in Apex's Navigation History functionality.
|
|
||
| public private(set) var isInPreview = false | ||
| private var currentStepIndex: Int? | ||
| public var currentStepIndex: Int? |
There was a problem hiding this comment.
How do we expect the application to use this property?
There was a problem hiding this comment.
@d-prukop - Can you comment on what you use this property for in Apex? Is it possible we can avoid needing it in a client app?
There was a problem hiding this comment.
@avi-c see my comments below. This and the exposing of reloadDataSource are related
| } | ||
|
|
||
| func reloadDataSource() { | ||
| open func reloadDataSource() { |
There was a problem hiding this comment.
In what scenarios would the application need to force a reload because the view controller isn’t automatically reloading?
There was a problem hiding this comment.
@1ec5 I tracked it down. The application actually doesn't need these things. This was part of an effort to prevent unnecessary passing of the navigation service to the guidance cards.
Currently the guidance cards have this code
extension InstructionsCardViewController: NavigationComponent {
public func navigationService(_ service: NavigationService, didUpdate progress: RouteProgress, with location: CLLocation, rawLocation: CLLocation) {
routeProgress = progress
reloadDataSource()
}
public func navigationService(_ service: NavigationService, didPassVisualInstructionPoint instruction: VisualInstructionBanner, routeProgress: RouteProgress) {
self.routeProgress = routeProgress
reloadDataSource()
}
public func navigationService(_ service: NavigationService, didRerouteAlong route: Route, at location: CLLocation?, proactive: Bool) {
self.currentStepIndex = nil
self.routeProgress = service.routeProgress
reloadDataSource()
}
}
and I wanted to try it out with this code
extension InstructionsCardViewController {
func routeProgressDidUpdate(_ progress: RouteProgress) {
routeProgress = progress
reloadDataSource()
}
func routeProgressDidPassVisualInstructionPoint(_ progress: RouteProgress) {
routeProgress = progress
reloadDataSource()
}
func routeProgressDidReroute(_ progress: RouteProgress) {
currentStepIndex = nil
routeProgress = progress
reloadDataSource()
}
}
This way we don't need to expose the entire nav service to the guidance cards or the UI side of the app.
I think we should move to make this change in InstructionsCardViewController
There was a problem hiding this comment.
Yes, let’s fold the extension into the main implementation.
There was a problem hiding this comment.
Per chat, replacing the existing extension with the one proposed in #2296 (comment) would break NavigationComponent conformance and thus NavigationViewController compatibility.
By design, all navigation components need to be aware of the navigation service because that’s how they get access to the route progress, and delegate methods always need to refer to the delegator. (Alternatively, a component could observe notifications, but we moved away from that mechanism because components kept failing to filter for specific senders.) We didn’t consider that it might be desirable to encapsulate NavigationService from UI code. (cc @JThramer)
Making currentStepIndex and reloadDataSource() public allows an application to reuse InstructionsCardViewController in a non-NavigationViewController environment while wrapping these NavigationServiceDelegate methods in custom methods that don’t necessarily expose NavigationService. Looking ahead to when we make the guidance card feature public, we can document these members as being public for the purpose of subclassing. (In general, we could do a better job of adding subclassing notes to class documentation anyways.)
Also re-expose the Route JSON string for use in debug metrics database.