Mapbox Version
11.18.3
React Native Version
0.84.1
Platform
iOS
@rnmapbox/maps version
10.3.0
Standalone component to reproduce
Prerequisite: Add any PNG imageset named pin to Images.xcassets in your Xcode project (1x/2x/3x). The app will crash on launch with EXC_BREAKPOINT in RNMBXStyle.symbolLayer().
import React from 'react';
import {
MapView,
ShapeSource,
SymbolLayer,
Images,
Camera,
} from '@rnmapbox/maps';
const pointFeature = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
id: '1',
properties: {
name: 'Test Point',
},
geometry: {
type: 'Point',
coordinates: [-74.00597, 40.71427],
},
},
],
};
class BugReportExample extends React.Component {
render() {
return (
<MapView style={{flex: 1}}>
<Camera centerCoordinate={[-74.00597, 40.71427]} zoomLevel={14} />
<Images nativeAssetImages={['pin']} />
<ShapeSource id="testSource" shape={pointFeature}>
{/* This SymbolLayer crashes the app on Fabric / New Architecture */}
<SymbolLayer
id="testSymbols"
style={{
iconImage: 'pin',
iconAllowOverlap: true,
}}
/>
</ShapeSource>
</MapView>
);
}
}
export default BugReportExample;
Observed behavior and steps to reproduce
On React Native 0.84 with the New Architecture (Fabric) enabled, the app crashes immediately when any SymbolLayer with an iconImage property is added to the map. The crash is a Swift assertion failure (EXC_BREAKPOINT / SIGTRAP) caused by a force-unwrap of nil on bridge! in RNMBXStyle.swift.
Under Fabric/bridgeless mode, RCTBridge is nil. The RNMBXStyle class holds bridge as weak var bridge: RCTBridge? (correctly optional), but all call sites in the auto-generated symbolLayer(), fillLayer(), etc. methods pass it as bridge!, which crashes when the optional is nil.
The crash also affects the component's addImages() method in RNMBXImages.swift, which passes bridge to RNMBXUtils.fetchImages() without a nil check.
Crash Stack Trace
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libswiftCore.dylib _assertionFailure(_:_:file:line:flags:) + 460
1 libswiftCore.dylib _assertionFailure(_:_:file:line:flags:) + 236
2 ImappRescue26.debug.dylib RNMBXStyle.symbolLayer(...) + 2156 (RNMBXStyle.swift:242)
3 ImappRescue26.debug.dylib RNMBXSymbolLayer.addStyles() + 1280 (RNMBXSymbolLayer.swift:80)
4 ImappRescue26.debug.dylib RNMBXLayer.addToMap(_:style:) + 920 (RNMBXLayer.swift:244)
Expected behavior
The images should be loaded and displayed instead of crashing the app.
Notes / preliminary analysis
RNMBXStyle.swift line 242 (and 9 other locations):
// RNMBXStyle.swift (auto-generated)
} else if (prop == "iconImage") {
styleValue.setImage(
bridge: bridge!, // <-- CRASH: bridge is nil under Fabric
style: style,
...
)
}
bridge is nil because Fabric/bridgeless mode does not provide an RCTBridge instance.
All 10 occurrences in RNMBXStyle.swift:
Line 56, 66, 145, 173, 242, 378, 545, 575, 894 (all bridge: bridge!)
Additionally, RNMBXImages.swift calls RNMBXUtils.fetchImages(bridge, ...) without guarding for nil.
Affected Code Paths
Any SymbolLayer using iconImage triggers the crash. The component with images={{ key: require('...') }} also crashes through addImages(). Only nativeAssetImages (which goes through addNativeImages using UIImage(named:)) avoids the bridge entirely.
Workaround / Suggested Fix
- RNMBXStyleValue.swift — Accept optional bridge
Change the setImage function signature from:
swiftfunc setImage(
bridge: RCTBridge,
...
to:
swiftfunc setImage(
bridge: RCTBridge?,
...
And guard the fetchImage call:
guard let bridge = bridge else {
// Fabric/bridgeless mode: bridge is nil, skip async image fetch.
// Image should already be loaded via <Images nativeAssetImages={...} />
setImageOnLayer(self)
return
}
RNMBXUtils.fetchImage(bridge, url:imageURI, scale:getImageScale(), callback:{ ...
RNMBXStyle.swift (auto-generated) — Remove force-unwrap
Replace all occurrences of bridge: bridge! with bridge: bridge:
// Before:
styleValue.setImage(bridge: bridge!, style: style, ...)
// After:
styleValue.setImage(bridge: bridge, style: style, ...)
- RNMBXImages.swift — Guard fetchImages call
// Before:
if missingImages.count > 0 {
RNMBXUtils.fetchImages(bridge, style: style, objects: missingImages, forceUpdate: true) { ...
// After:
if missingImages.count > 0, let bridge = bridge {
RNMBXUtils.fetchImages(bridge, style: style, objects: missingImages, forceUpdate: true) { ...
Additional links and references
No response
Mapbox Version
11.18.3
React Native Version
0.84.1
Platform
iOS
@rnmapbox/mapsversion10.3.0
Standalone component to reproduce
Prerequisite: Add any PNG imageset named
pintoImages.xcassetsin your Xcode project (1x/2x/3x). The app will crash on launch withEXC_BREAKPOINTinRNMBXStyle.symbolLayer().Observed behavior and steps to reproduce
On React Native 0.84 with the New Architecture (Fabric) enabled, the app crashes immediately when any SymbolLayer with an iconImage property is added to the map. The crash is a Swift assertion failure (EXC_BREAKPOINT / SIGTRAP) caused by a force-unwrap of nil on bridge! in RNMBXStyle.swift.
Under Fabric/bridgeless mode, RCTBridge is nil. The RNMBXStyle class holds bridge as weak var bridge: RCTBridge? (correctly optional), but all call sites in the auto-generated symbolLayer(), fillLayer(), etc. methods pass it as bridge!, which crashes when the optional is nil.
The crash also affects the component's addImages() method in RNMBXImages.swift, which passes bridge to RNMBXUtils.fetchImages() without a nil check.
Crash Stack Trace
Expected behavior
The images should be loaded and displayed instead of crashing the app.
Notes / preliminary analysis
RNMBXStyle.swift line 242 (and 9 other locations):
bridge is nil because Fabric/bridgeless mode does not provide an RCTBridge instance.
All 10 occurrences in RNMBXStyle.swift:
Line 56, 66, 145, 173, 242, 378, 545, 575, 894 (all bridge: bridge!)
Additionally, RNMBXImages.swift calls RNMBXUtils.fetchImages(bridge, ...) without guarding for nil.
Affected Code Paths
Any SymbolLayer using iconImage triggers the crash. The component with images={{ key: require('...') }} also crashes through addImages(). Only nativeAssetImages (which goes through addNativeImages using UIImage(named:)) avoids the bridge entirely.
Workaround / Suggested Fix
Change the setImage function signature from:
to:
And guard the fetchImage call:
RNMBXStyle.swift(auto-generated) — Remove force-unwrapReplace all occurrences of
bridge: bridge!withbridge: bridge:Additional links and references
No response