Skip to content

Remove need for developers to implement NavigationMapView.updateCourseTracking(location:animated:)#1542

Closed
bsudekum wants to merge 4 commits into
masterfrom
handle-updates
Closed

Remove need for developers to implement NavigationMapView.updateCourseTracking(location:animated:)#1542
bsudekum wants to merge 4 commits into
masterfrom
handle-updates

Conversation

@bsudekum
Copy link
Copy Markdown
Contributor

@bsudekum bsudekum commented Jul 4, 2018

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, when NavigationMapView is inited, we already have a location and the view will be properly centered.

/cc @1ec5 @frederoni

frederoni
frederoni previously approved these changes Jul 5, 2018
preferredFramesPerSecond = FrameIntervalOptions.pluggedInFramesPerSecond
}

updateCourseTracking(location: location, animated: true)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

NotificationCenter.default.addObserver(self, selector: #selector(progressDidChange(_:)), name: .routeControllerProgressDidChange, object: nil)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@1ec5 this may require changing the initializer on NavigationMapview. We currently have no RouterController props to grab.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess making this an optional property is another option. If you only want to update a single map view, set this prop.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we leave this method public? Is there still a use case for manually updating the course view independently of a route controller?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔maybe. I think it might be wise to wrap these types of functions in a more specific helper function like recenterMap:

@objc public func recenterMap() {
tracksUserCourse = true
enableFrameByFrameCourseViewTracking(for: 3)
}

open var tracksUserCourse: Bool = false {
didSet {
guard let _ = routeController, tracksUserCourse == true else {
print("NavigationMapView.routeController must non-nil to set tracksUserCourse to true.")
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about suspending notifications on the previous route controller?

@bsudekum
Copy link
Copy Markdown
Contributor Author

bsudekum commented Jul 9, 2018

@1ec5 I'm not sure the road we're headed down is any better, in fact it could be worse. I'm going to close this out and move the good parts found in this pr to #1547.

@bsudekum bsudekum closed this Jul 9, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants