Remove need for developers to implement NavigationMapView.updateCourseTracking(location:animated:)#1542
Remove need for developers to implement NavigationMapView.updateCourseTracking(location:animated:)#1542bsudekum wants to merge 4 commits into
Conversation
…eTracking(location:animated)
| preferredFramesPerSecond = FrameIntervalOptions.pluggedInFramesPerSecond | ||
| } | ||
|
|
||
| updateCourseTracking(location: location, animated: true) |
There was a problem hiding this comment.
This method is already risky and could become moreso if we rely on notifications to drive course updates as opposed to manual calls to updateCourseTracking(location:animated:). NavigationMapView apparently listens for notifications coming from any RouteController, so every map view in the application will automatically respond to every route controller in the application. There’s a high potential for crosstalk. We’d need to pass in a specific route controller as the object here to avoid that problem:
There was a problem hiding this comment.
@1ec5 this may require changing the initializer on NavigationMapview. We currently have no RouterController props to grab.
There was a problem hiding this comment.
I guess making this an optional property is another option. If you only want to update a single map view, set this prop.
There was a problem hiding this comment.
When we implemented #402, the idea was that moving the course view was the responsibility of the view controller that contains the map view, not the map view itself, since the view controller knows about its route controller for sure. I think we could’ve made that more clear by making the course view a sibling of the map view instead of one of its views. Relying on a global notification is a poor way to make the map view aware of the view controller’s route controller. Changing the initializer is also problematic because map views are often created using the init(frame:) or init(coder:) initializer.
If you only want to update a single map view, set this prop.
I don’t think it should be something that you only use in some cases. If we make the route controller a property, then the view controller should always have to set this property on the map view in order to keep the course view in sync. Otherwise, how would the map view handle the route controller swapping that happens around tunnels?
There was a problem hiding this comment.
How would someone add a NavigationMapView to a storyboard if they have not yet created a route controller to pass through?
| } | ||
|
|
||
| @objc public func updateCourseTracking(location: CLLocation?, animated: Bool) { | ||
| @objc func updateCourseTracking(location: CLLocation?, animated: Bool) { |
There was a problem hiding this comment.
Should we leave this method public? Is there still a use case for manually updating the course view independently of a route controller?
There was a problem hiding this comment.
🤔maybe. I think it might be wise to wrap these types of functions in a more specific helper function like recenterMap:
mapbox-navigation-ios/MapboxNavigation/NavigationMapView.swift
Lines 1064 to 1067 in 0b69c32
| open var tracksUserCourse: Bool = false { | ||
| didSet { | ||
| guard let _ = routeController, tracksUserCourse == true else { | ||
| print("NavigationMapView.routeController must non-nil to set tracksUserCourse to true.") |
There was a problem hiding this comment.
I'd be open to making this an assertion. Fail fast.
| open var tracksUserCourse: Bool = false { | ||
| didSet { | ||
| guard let _ = routeController, tracksUserCourse == true else { | ||
| print("NavigationMapView.routeController must non-nil to set tracksUserCourse to true.") |
There was a problem hiding this comment.
tracksUserCourse is basically redundant to routeController now. We can move all the logic below into routeController’s setter, conditioned on whether routeController is non-nil.
There was a problem hiding this comment.
And we can rename routeController to something that makes its purpose clear, like userCourseController (which would suggest a protocol by that name based on RouteController’s interface).
|
|
||
| open var routeController: RouteController? { | ||
| didSet { | ||
| resumeNotifications() |
There was a problem hiding this comment.
What about suspending notifications on the previous route controller?
Closes: #1539
It's not very obvious developers need to update the user puck if they implement their own NavigationMapView and this view can easily handle update the puck when progress notifications occur.
This PR makes
NavigationMapView.updateCourseTracking(location:animated:)private turns on the location manager sooner. This way, whenNavigationMapViewis inited, we already have a location and the view will be properly centered./cc @1ec5 @frederoni