Skip to content

fix(ios): stop emitting navigation events after NavModule is invalidated - #695

Open
sr1k3sh wants to merge 1 commit into
googlemaps:mainfrom
sr1k3sh:fix/ios-emit-after-invalidate
Open

sr1k3sh wants to merge 1 commit into
googlemaps:mainfrom
sr1k3sh:fix/ios-emit-after-invalidate

Conversation

@sr1k3sh

@sr1k3sh sr1k3sh commented Nov 2, 2026

Copy link
Copy Markdown

Fixes #539

Problem
NavModule is a process-wide singleton (allocWithZone + dispatch_once) that outlives the React Native instance. On a reload (CMD+R, fast refresh) nothing detaches it from the navigator / road-snapped location provider, so the next navigator callback emits through the event emitter of the torn-down runtime and the app aborts.

Reproduced on main (v0.18.0), example app, iPhone 16 Pro simulator (iOS 18.6): start guidance + route simulation, then reload:

-[GMSNavigator routeProgressMonitor:didUpdateRemainingTime:]
  -[NavModule navigator:didUpdateRemainingTime:]
    -[NavModule onRemainingTimeOrDistanceChangedWithNavigator:]
      -[NativeNavModuleSpecBase emitOnRemainingTimeOrDistanceChanged:]
        NativeNavModuleSpecJSI … unordered_map<…IAsyncEventEmitter> insert
          → std::__throw_overflow_error → abort (SIGABRT)

Fix

  • Implement invalidate (called by React Native on reload) to remove the navigator and road-snapped location listeners and drop the event emitter, on the main queue.
  • Skip emitting in the INavigationCallback methods while no emitter is set (same check NavAutoModule already uses).
  • On the next initialization, initializeSession re-adds the listeners and setEventEmitterCallback restores the emitter, so events keep working after a reload.

Testing
Example app, iPhone 16 Pro simulator, iOS 18.6, Navigation SDK 11.1.0:

  • Before: reload during simulated guidance crashes (stack above).
  • After: 3/3 reloads during active guidance, no crash; after reload, navigation re-initializes, and onStartGuidance / remaining-time updates reach JS again.

Not tested on Android (change is iOS-only).

NavModule is a process-wide singleton that outlives the React Native
instance. On a reload (CMD+R, fast refresh) it stayed registered as the
navigator and road-snapped location listener, and the next callback
emitted through an event emitter bound to the torn-down runtime, crashing
the app.

Implement invalidate to detach both listeners and drop the emitter, and
skip emitting while no emitter is set. initializeSession re-adds the
listeners and setEventEmitterCallback restores the emitter on the next
initialization.

Fixes googlemaps#539
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.

[Bug]: iOS crash during dev reload — NavModule event emitters called with invalid bridge

2 participants