App crashes on AppLoading splash screen on fresh installs for some users

Please provide the following:

  1. SDK Version: 35
  2. Platforms(Android/iOS/web/all): iOS (that we know of)

Some of our users are experiencing instant app crashes on the splash screen of our app. The users affected seem to all

  • Run iOS
  • Perform a fresh install

However, we can’t reproduce internally. It doesn’t seem to be all fresh installs either, as one of our users ‘fixed’ the issue by instead installing on her iPad, and other users have reported to just use another phone which worked fine.

Looking at Sentry, we get a decent amount of “Cannot download [assetlink on Cloudfront]” errors,

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, leading me to think the crash might have something to do with the asset caching code done during the AppLoading screen. It’s pretty much copy+paste from the guide in the docs, but I’m running out of ideas.

I’ve tried publishing a new OTA update, as well as new binaries, but neither has helped. We include everything in our assets folder in the binary bundle, so it seems weird if downloading them is an issue:

"assetBundlePatterns": ["assets/*"],
image

The app is called “Brandheroes” on the app store, if anyone can reproduce I’d love to know!

A short summary of our caching code can be seen below. Any and all advice is much appreciated.

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...
};

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.