Skip to content

[Bug]: iOS 26: SIGTRAP in RNMBXImages.addImages (placeholderImage force unwrap) #4260

Description

@angelolencina

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug 🪲Something isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions