Repository navigation
[Bug]: iOS 26: SIGTRAP in RNMBXImages.addImages (placeholderImage force unwrap) #4260
Description
Mapbox Version
11.18.3
React Native Version
0.85.3
Platform
iOS
@rnmapbox/maps version
10.3.1
Standalone component to reproduce
import React from 'react';
import {
MapView,
ShapeSource,
SymbolLayer,
Images,
Camera,
} from '@rnmapbox/maps';
const aPoint = {
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [-74.00597, 40.71427],
},
properties: {icon: 'marker'},
};
class BugReportExample extends React.Component {
render() {
return (
<MapView style={{flex: 1}}>
<Camera centerCoordinate={[-74.00597, 40.71427]} zoomLevel={14} />
<Images images={{marker: 'https://example.com/marker.png'}} />
<ShapeSource id="idPointSource" shape={aPoint}>
<SymbolLayer id="idPointLayer" style={{iconImage: ['get', 'icon']}} />
</ShapeSource>
</MapView>
);
}
}Observed behavior and steps to reproduce
Environment
- @rnmapbox/maps 10.3.1 (checked 10.3.2, same code there)
- react-native 0.85.3, new architecture
- iOS 26.5, iPhone14,7 (real device)
We started getting hard crashes in production once users updated to iOS 26. It's a SIGTRAP on the main thread when the style loads and images get added to the map:
0 RNMBXImages.addImages(style:images:oldImages:)
1 RNMBXImages.addImages(style:images:oldImages:)
2 RNMBXImages.addToMap(_:style:)
3 closure #1 (MapView) in RNMBXMapView.addToMap(UIView)
...
13 @objc RNMBXMapView.didSetProps([String])
14 -[RNMBXMapViewComponentView updateProps:oldProps:]
Standalone code example
Nothing special needed — any MapView with an n iOS 26 as soon as the style loads andaddImages runs. Same build works fine on iOS 17/18 devices.
import React from 'react';
import Mapbox from '@rnmapbox/maps';
Mapbox.setAccessToken('pk.xxx');
export default function App() {
return (
<Mapbox.MapView style={{flex: 1}}>
<Mapbox.Camera zoomLevel={14} centerCoordinate={[8.54, 47.37]} />
<Mapbox.Images images={{marker: 'https://example.com/marker.png'}} />
<Mapbox.ShapeSource
id="items"
shape={{
type: 'FeatureCollection',
features: [
{
type: 'Feature',
geometry: {type: 'Point', coordinates: [8.54, 47.37]},
properties: {icon: 'marker'},
},
],
}}>
<Mapbox.SymbolLayer id="items-symbols" style={{iconImage: ['get', 'icon']}} />
</Mapbox.ShapeSource>
</Mapbox.MapView>
);
}The trap is the force unwrap in placeholderImage (RNMBXImages.swift):
lazy var placeholderImage : UIImage = {
UIGraphicsBeginImageContextWithOptions(CGSialse, 0.0)
let result = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
return result
}()UIGraphicsBeginImageContext* has been deprecated since iOS 17, and on iOS 26 the context creation fails, so UIGraphicsGetImageFromCurrentImageContext() returns nil and the ! traps. In practice every user on iOS 26 crashes
on any screen that renders a map with Images.
Switching to UIGraphicsImageRenderer fixes it
lazy var placeholderImage : UIImage = {
return UIGraphicsImageRenderer(size: CGSize(width: 1, height: 1)).image { _ in }
}()takeSnap in RNMBXMapView.swift has the same I patched that one too.
This is the patch we're shipping via patch-pa
diff --git a/node_modules/@rnmapbox/maps/ios/RNMBX/RNMBXImages.swift b/node_modules/@rnmapbox/maps/ios/RNMBX/RNMBXImages.swift
index b89393d..0072a24 100644
--- a/node_modules/@rnmapbox/maps/ios/RNMBX/RNMBXImages.swift
+++ b/node_modules/@rnmapbox/maps/ios/RNMBX/RNMBXImages.swift
@@ -267,10 +267,7 @@ open class RNMBXImages : UIView, RNMBXMapComponent {
}
lazy var placeholderImage : UIImage = {
- UIGraphicsBeginImageContextWithOptions(C, false, 0.0)
- let result = UIGraphicsGetImageFromCurrentImageContext()!
- UIGraphicsEndImageContext()
- return result
+ return UIGraphicsImageRenderer(size: CGSimage { _ in }
}()
}
diff --git a/node_modules/@rnmapbox/maps/ios/RNMBX/RNMBXMapView.swift b/node_modules/@rnmapbox/maps/ios/RNMBX/RNMBXMapView.swift
index 62861b5..dfee057 100644
--- a/node_modules/@rnmapbox/maps/ios/RNMBX/RNMBXMapView.swift
+++ b/node_modules/@rnmapbox/maps/ios/RNMBX/RNMBXMapView.swift
@@ -1506,13 +1506,13 @@ extension RNMBXMapVie
@objc public func takeSnap(
writeToDisk:Bool) -> URL
{
- UIGraphicsBeginImageContextWithOptions(self.bounds.size, true, 0);
-
- self.drawHierarchy(in: self.bounds, afte
- let snapshot = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
+ let format = UIGraphicsImageRendererFormat()
+ format.opaque = true
+ let snapshot = UIGraphicsImageRenderer(b: format).image { _ in
+ self.drawHierarchy(in: self.bounds, afterScreenUpdates: true)
+ }
- return writeToDisk ? RNMBImageUtils.createTempFile(snapshot!) : RNMBImageUtils.createBase64(snapshot!)
+ return writeToDisk ? RNMBImageUtils.createTempFile(snapshot) : RNMBImageUtils.createBase64(snapshot)
}
}Expected behavior
No response
Notes / preliminary analysis
No response
Additional links and references
No response
Activity
fix(ios): apply camera updates made while the map is off-window; repl…