Expo iOS13 crashes instantly on startup

Please provide the following:

  1. SDK Version: 35
  2. Platforms(Android/iOS/web/all): iOS 13

This has happened to a small subset of users for the past couple of weeks. I searched around last week, and thought that the issue was similar to this or this, so I bumped the expo-web-browser to 7.0.1, built a new standalone binary using the new builders, and published the new version on October 30th.

But alas, we still have users that report this issue. How can I move forward? Right now, we use Sentry for error reporting, but it seems Sentry never manages to get instantiated before this crash.

1 Like

Maybe @esamelson knows something, pinging you as you were active in the other issue

Hi there-- do you have a stacktrace for the crash? If you can reproduce it, you can hook a device up to your mac and use the Console application to view logs. It’s pretty hard to tell what’s going on without more information here, unfortunately.

Just chiming in here to say that we’re having the same issue. Only 2 reports of it so far, so again a very small subset of users only. I myself am on iOS13 and everything is working fine.

The commonality appears related to those who have recently bought new phones (iPhone 11 Pro), so not specifically iOS version. I too have a new iPhone 11 Pro but I restored from an iCloud backup. In at least 1 of the 2 cases we have they have restored on the new phone using the ‘copy from old phone’ method. So there might be something corrupt coming across, or some security problem, not sure.

I’ll report back here if I find out more. At this stage I don’t have any logs or any useful help info, just know we’re having the same trouble!

Unfortunately not x2 - we don’t have crash reports for non-JS, as we haven’t before had any problems with native crashes, so Sentry suited our needs just fine. We have no idea how to replicate, I’ve tried on 4 different physical devices with iOS12/13 installed, as well as on emulators, but they all work fine. And, as I mentioned, it works fine for most of our users, it only seem to affect a handful, and we have a 3-4k monthly active users at the moment.

Can’t figure out what to use for Firebase/Crashlytics with the Expo managed workflow, deprecations and slightly-different-named-packaged abound :smile: Can you point me in the right direction? Fx this? Or do you have another recommendation for gathering native crash reports?

And thanks for chiming in @markos , it’s always nice to know we’re not the only ones :smile: Our affected users are on newer iPhones (8 and above) with iOS13 across the board.

We had this issue and it seemed to be mostly iPhone Xr and Xs models, but only when they had “Guided Access” turned on. Once the users turned that off it resolved it for all of them.

Interesting! I’ll try to ask one of the users we know is experiencing the issue to see if this is the case for her :+1: I’ll post back here when I know

No dice, unfortunately

Thanks @clwendt88 I think this was our issue too! I can enable guided access on my phone and reproduce the crash.

Is this a new feature in ios13 that expo doesn’t fully support yet?

I don’t think it’s a new iOS feature, but it seemed to start causing an issue with iOS 13 on certain devices. There were only a few users that had it turned on, so we didn’t dig in to find a fix that resolves the crash while it’s turned on. (we just had those users turn it off)

Any advice about how to proceed here? According to the Expo Docs on Error Handling, there’s no way for me to gather native crash logs on iOS from my users, and I can’t reproduce it myself with neither simulator nor the two physical iPhones I have available. @esamelson

I’m experiencing this same issue. It happens on a completely fresh simulator install. The simulator has no Guided Access either.

We’ve combed through device logs, and were able to find this:

*** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘*** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[0]’
*** First throw call stack:
(
	0  CoreFoundation           0x0000000111ebe1ab __exceptionPreprocess + 171
	1  libobjc.A.dylib           0x0000000110ad6f41 objc_exception_throw + 48
	2  CoreFoundation           0x0000000111efdf9c _CFThrowFormattedException + 194
	3  CoreFoundation           0x0000000111dd2b41 -[__NSPlaceholderDictionary initWithObjects:forKeys:count:] + 321
	4  CoreFoundation           0x0000000111dd29cb +[NSDictionary dictionaryWithObjects:forKeys:count:] + 59
	5  Exponent              0x00000001041bb94b __41-[SEGIntegrationsManager refreshSettings]_block_invoke_3 + 208
	6  Exponent              0x00000001041b6cbe __seg_dispatch_specific_block_invoke + 25
	7  libdispatch.dylib          0x000000<…>

Would appreciate any insight anyone has, because our development is at a standstill.

is this happening on a brand new project too?

are you using Segment in your project?

Yep. We are using Segment, but we’ve sorted it out.

For us, this issue was due to a missing entry in our config file, being referenced by Segment. I assume that’s what the attempt to insert nil object from objects[0] is all about.

If anyone else is experiencing this kind of error, and it’s not due to Guided Access, it’s a good idea to check and make sure values are being passed to native libraries properly.

1 Like

Just out of curiosity, what was the missing entry @t3rminus ?

In our case, we were initializing segment like this:

Segment.initialize({ androidWriteKey: config.SEGMENT_ANDROID, iosWriteKey: config.SEGMENT_IOS });

but config.SEGMENT_ANDROID and config.SEGMENT_IOS were both undefined. This was causing the app to crash instantly on launch, with no error messages, other than ones buried in the device’s system logs.

TL;DR We get a handful of “Cannot download [assetlink on Cloudfront]” errors on Sentry, leading me to think the crash might have something to do with the asset caching code done during the AppLoading screen - might there be some issue for clean installs and assets provided OTA (that are not a part of a binary?)

It occurred to me recently that since the user’s did get to see our AppLoading splash, that the error might be related to the asset caching code that runs while it shows. It’s pretty much copy+paste from the guide in the docs, but I’m running out of ideas.

A short summary here:

AppContainer.tsx

const loadAssets = async () => await loadAndCacheAssets();

  if (!isReady) {
    return (
      <GenericErrorBoundary prefix="AppLoading">
        <AppLoading startAsync={loadAssets} onFinish={() => setIsReady(true)} onError={handleLoadingError} />
      </GenericErrorBoundary>
    );
  }

// else return full app
export const loadAndCacheAssets = async () => {
  try {
    // Cache bundled image assets
    const imageAssets = await cacheImages(getAllImagesFromAssets());
    // Cache remote fonts and font icons
    const fontAssets = cacheFonts([
      FontAwesome.font,
      // ...other fonts
    ]);

    // Download and cache locally bundled fonts
    const loadFonts = Font.loadAsync(require('./../assets/fonts/RobotoRegular.ttf'));
    await Promise.all([...imageAssets, ...fontAssets, loadFonts]);
  } catch (error) {
    console.log(`Error loading assets\n${error}`);
    captureException(error);
  }
};

const cacheImages = async (images: any[]) => {
  return await images.map(async (image: any) => {
    if (typeof image === 'string') {
      return Image.prefetch(image);
    } else {
      try {
        return await Asset.fromModule(image).downloadAsync();
      } catch (e) {
        console.warn(`There was an error downloading an image. The error was: ${e}`);
        captureException(e);
      }
    }
  });
};

const cacheFonts = (fonts: any) => {
  return fonts.map((font: any) => Font.loadAsync(font));
};

const getAllImagesFromAssets = () => {
  const appIcons = Object.keys(Images.appIcons).map(key => Images.appIcons[key]);
  const backgrounds = Object.keys(Images.backgrounds).map(key => Images.backgrounds[key]);
  const images = Object.keys(Images.images).map(key => Images.images[key]);
  const tabBarIcons = Object.keys(Images.tabbarIcons).map(key => Images.tabbarIcons[key]);
  return [...appIcons, ...backgrounds, ...images, ...tabBarIcons, Images.curvedArrow, Images.pushPermissionButton];
};

Images.ts

export const Images = {
  appIcons: {
    shopIcon: require('./../assets/icons/shop-icon.png'),
    // ... other icons
  },
  images: {
    wink: require('./../assets/images/wink.gif'),
    // more images
  },
  // and some more...
};

I then found some errors on Sentry that might confirm my suspicion - a lot of

Could not download from 'https://d1wp6m56sqw74a.cloudfront.net/~assets/1bc5a7992af35c03a9323043b2efe23a

where the assets vary, but are all some of the assets that are bundled with the app.

The issue seems to mostly affect new (re)-installs of the app - might there be some issue with OTA updates for assets?

@esamelson - I think this might be the closest thing to a stack trace I can provide. Any thoughts about my theory that the crash could be due to asset caching, and OTA provided assets might have some issues being delivered to fresh binary installs?

This makes me sad because my app does a similar crash and I just installed Sentry thinking it would be able to catch it, haha.

2 Likes

For me the issue was also “Guided Access” turned on.