react-native-maps: Exception thrown while executing UI block: * -[__NSDictionaryM setObject:forKeyedSubscript:]: key cannot be nil

Bug report

Summary

`Exception thrown while executing UI block: * -[__NSDictionaryM setObject:forKeyedSubscript:]: key cannot be nil

__44-[RCTUIManager flushUIBlocksWithCompletion:]_block_invoke RCTUIManager.m:1201 __44-[RCTUIManager flushUIBlocksWithCompletion:]_block_invoke.498 __RCTExecuteOnMainQueue_block_invoke 82506F82-C97A-3CF2-BA6C-ACA532D8AA49 82506F82-C97A-3CF2-BA6C-ACA532D8AA49 _dispatch_main_queue_callback_4CF 0E00CA08-C176-30F7-9CF9-445B374C0686 0E00CA08-C176-30F7-9CF9-445B374C0686 CFRunLoopRunSpecific GSEventRunModal 280B8BEE-0493-3862-B922-9A87C5F46EE8 UIApplicationMain main start`

Environment info

"react-native": "0.66.1",
      "react": "17.0.2"
      "react-native-maps": "^0.29.3",

Steps to reproduce

npx react-native run-ios

when return screen have this issue

Reproducible sample code

<MapView initialRegion={{ latitude: -1.395197, longitude: -78.423335, latitudeDelta: 0.009999, longitudeDelta: 0.009999, }} style={{height: 200}} provider={PROVIDER_GOOGLE} customMapStyle={mapStandardStyle} showsUserLocation={true} > <Marker coordinate={{ latitude: latitude, longitude: longitude, }}> <Image resizeMode=“cover” style={styles.marker} source={require(‘…/…/…/…/assets/img/map-pin.png’)} /> </Marker> </MapView>

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 12
  • Comments: 23

Most upvoted comments

This is not an issue regarding this project, instead it’s an implementation detail difference between GoogleMaps and apple MapKit on iOS.

mainly Apple MapKit supports UIView object inside markers, it knows how to display them. which means if you create a react element inside the marker <Image> in the above example a UIKit view element is created UIImage and added when AppleMaps is used.

but Google Maps don’t support native UIKit Views (I think they even render using openGL). so when react native tries to create a view inside the Marker … everything breaks.

this project at the end of the day is limited by what is possible via the native maps libraries used, so I would recommend looking here: https://developers.google.com/maps/documentation/ios-sdk/marker and see what’s possible when it comes to GoogleMaps on iOS before attempting to use it.

I just solved this by upgrading my "react-native-reanimated" to "^3.0.0-rc.10". (was 3.0.0-rc.3). I checked the change log, and I think this bug was related to entering and exiting props of reanimated.

Using the Apple Maps implementation on iOS solves the problem for me (i.e. dropping the provider={PROVIDER_GOOGLE} prop).

but Google Maps don’t support native UIKit Views (I think they even render using openGL). so when react native tries to create a view inside the Marker … everything breaks.

I’m not convinced this is the case since the markers do render the first time no problem. The issue seems to be when a key is dropped. This would explain why some developers are mentioning using indexes as a key rather than ids.

@salah-ghanim @ingvardm This only started to happen when upgrading react-reanimated to 2.10.0 version. Before it worked fine even with such markers. So its about some interdependency in the animation core it seems.

This happens only when the marker has children. For my solution i can use images instead of nested views on iOS, see if you can do the same. Also you can try getting the position of thee marker (onLayout) and use that to place your whatever on top of it.

Facing the same issue with SDK 48. Cannot upgrade reanimated to 3.3.0 cause SDK 48 doesn’t support above 2.14.4 Will try to update expo SDK

Originally posted this comment on a separate issue thread, but figured I would post here since this thread has a lot of activity.

I have written a blog post if you are interested in reading about my solution a little bit more, but if not, I’ll add the TL;DR in this comment.

Here’s the blog post

And here is the TL;DR:

If you are getting the error Exception thrown while executing UI block: * -[__NSDictionaryM setObject:forKeyedSubscript:]: key cannot be nil while trying to use custom markers with Google Maps on iOS via react-native-maps, it is possible the root cause is a conflict with react-native-reanimated.

I don’t know exactly what the conflict is, however, I have two solutions that may work for you!

Solution 1

If feasible, you can remove react-native-reanimated from your project and that should resolve the issue for you.

If that isn’t an option, I would encourage you to rebuild your map in a test project without reanimated, and implement your map so that you are using custom markers (and it should work). Then, reintroduce reanimated into that project, and add your desired functionality in piece wise until you can isolate what method in reanimated is causing the error. In our case, it was our use of FadeInUp and FadeInOut. Your mileage may vary, but you should be able to find alternative animation solutions while preserving your app’s behaviour.

Solution 2

Agnostic of any react-native-reanimated conflicts, this error is thrown because the indices from the marker array you’re mapping over are bring dropped in the case that the marker array length, n, is changing such that n' < n.

You can create a hook that will always return a constant sized array containing marker objects to your map view, so that it may map your objects to custom markers. For every index in this array, there will exist either a real marker object that renders on the map, or a buffer object that will not render on the map. Either way, the indices being used as keys will always exist, therefore you will not hit this error.

I’m facing the same issue when trying to cluster markers and if the point is a cluster render circle with the number of points. Is there any workaround to render such a custom marker without crashing?