Skip to content

iOS: travel mode is lost when setDestinations runs before the NavigationView attaches, route computes as driving #655

Description

@christian-apollo

Is there an existing issue for this?

  • I have searched the existing issues

Description of the bug

On iOS, the travelMode passed to setDestinations (in routingOptions or routeTokenOptions) is only applied to the GMSMapView of each NavigationView registered at that instant. It is never set on the GMSNavigationSession, whose navigator computes the route and whose travelMode defaults to driving.

When setDestinations runs before the NavigationView has attached to the session, the mode is lost and the route is computed as a driving route. This is the normal state for the first request after a launch in an app that mounts the NavigationView in the same React commit that starts guidance: the native view is created and registered, but attachToNavigationSessionIfNeeded only runs on its first non-zero layout, so the value set on the not-yet-attached map view never reaches the session.

Calling setDestinations again once the view is attached returns the correct route, which is why "change the travel mode and change it back" works around it.

Android is not affected: the mode travels inside RoutingOptions on every request.

iOS Platform

  • iOS

Android Platform

  • Android

React Native version

0.86.3

React version

19.2.8

Package version

0.17.1 (the code is unchanged on main at 0.17.2)

Native SDK versions

iOS GoogleNavigation 11.1.0, Android navigation 7.9.0 (as pinned by the package)

Steps to reproduce

  1. Cold launch an app that renders a MapView on its home screen and swaps it for a NavigationView when a destination is chosen, calling setDestinations(..., {routingOptions: {travelMode: TravelMode.CYCLING}}) from an effect in that same render.
  2. Call startGuidance().
  3. Read getCurrentTimeAndDistance() or look at the route.
  4. Change the travel mode and call setDestinations again with the view now attached.

Expected vs Actual Behavior

Expected: the first route honours TravelMode.CYCLING.

Actual: the first route is a driving route. On a ~20 km test route (Montreal downtown to YUL, iPhone 17 Pro simulator, iOS 26.4) the first request returned 18.2 km in 46 min with delaySeverity: 2, which only driving routes carry; an explicit cycling request on the attached view returned 29.7 km in 96 min with delaySeverity: 0, and walking 18.6 km in 4 h 20. With the fix in the linked pull request the first request returns the 29.6 km / 96 min cycling route.

Code Sample

// Rendered as soon as a destination is chosen; NavigationView mounts in this same commit.
useEffect(() => {
  if (!destination || !isNavigationInitialized) return;
  navigationController.setDestinations([{title: destination.name, position: destination}], {
    routingOptions: {travelMode: TravelMode.CYCLING, avoidHighways: true},
    displayOptions: {showDestinationMarkers: true},
  }).then(() => navigationController.startGuidance());
}, [destination, isNavigationInitialized]);

Additional Context

NavModule.mm configureNavigatorWithTravelMode: forwards to [NavViewModule setTravelMode:], which loops over viewControllersRegistry and calls [_mapView setTravelMode:]. GMSNavigationSession exposes its own travelMode property and it is never written. The fix is to set it there before updating the views, and to have a view that attaches later copy the session's mode.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

priority: p2Moderately-important priority. Fix may not be included in next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions