googlemaps / googlemaps/react-native-navigation-sdk

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

Offen
#655 0 Kommentare 0 Reaktionen 1 zugewiesene Person Beansprucht von @jokerttu Auf GitHub ansehen
Vorherrschende Sprache
TypeScript
Sterne
227
Forks
38
Ø Merge
5 T. 7 Std.
Gemergte PRs (30 T.)
10

Beschreibung

### Is there an existing issue for this?

- [x] 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

- [x] 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

```ts
// 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.

Beitragsleitfaden

Beitragsleitfaden öffnen

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.