Skip to content

iOS Mobile App Build Fix Procedure

This document outlines the definitive, repeatable procedure for fixing build issues in the React Native / Expo mobile apps within this monorepo. This “wipe and rebuild” strategy should be followed for any app that fails to build or run, especially after initial setup or significant changes.

This procedure is based on the “known-good” configuration of the altFinder_app-mobile and bonjour_it_com-mobile applications. By following these steps, we are standardizing all other mobile apps to match the setup of the ones that are confirmed to build and run successfully.

The core issues this procedure resolves are:

  1. Incorrect CocoaPods autolinking commands in the Podfile.
  2. Build failures related to AppDelegate.swift and the React Native New Architecture.
  3. Network errors during the expo prebuild step that prevent clean rebuilds.

Follow these steps exactly for each mobile app that needs to be fixed.

This step wipes the existing native iOS project and regenerates it from scratch. We must force the command to use yarn to bypass a known npm network error.

Replace <app-name> with the name of the app you are fixing (e.g., bonjour_locker-mobile).

Terminal window
NPM_CONFIG_USER_AGENT="yarn" yarn nx run <app-name>:prebuild --clean

The default AppDelegate.swift generated by Expo is incompatible with our setup. It must be replaced with the standard Objective-C++ version.

  1. Delete the Swift file:

    Terminal window
    rm apps/<path-to-app>/mobile/ios/<project-name>/AppDelegate.swift

    (Example: rm apps/bonjour_services/bonjour_locker/mobile/ios/bonjourlockermobile/AppDelegate.swift)

  2. Create AppDelegate.h: Create a new file named AppDelegate.h in the same directory with the following content:

    #import <Expo/Expo.h>
    #import <React/RCTBridgeDelegate.h>
    #import <UIKit/UIKit.h>
    @interface AppDelegate : EXAppDelegate <RCTBridgeDelegate>
    @end
  3. Create AppDelegate.mm: Create a new file named AppDelegate.mm in the same directory with the following content:

    #import "AppDelegate.h"
    #import <React/RCTBundleURLProvider.h>
    @implementation AppDelegate
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
    self.moduleName = @"main";
    // You can add your custom initial props in the dictionary below.
    // They will be passed down to the ViewController used by React Native.
    self.initialProps = @{};
    return [super application:application didFinishLaunchingWithOptions:launchOptions];
    }
    - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
    {
    #if DEBUG
    return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.js"];
    #else
    return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
    #endif
    }
    @end

The prebuild command may still generate a Podfile with an incorrect autolinking command. We need to ensure it uses the correct Node.js evaluation script.

  1. Open the Podfile: Located at apps/<path-to-app>/mobile/ios/Podfile.

  2. Find and Replace the config_command: Locate the line that starts with config_command =. It will look something like this:

    config_command = ['npx', 'expo-modules-autolinking', 'ios', '--platform', 'ios', '--json', '--search-paths', pod_search_paths.join(',')]

    Replace it with this exact line:

    config_command = ['node', '--eval', "require('expo/scripts/autolinking').createConfigAsync({ platform: 'ios' }).then(c => console.log(JSON.stringify(c)))", '--', '--search-paths', pod_search_paths.join(',')]

Finally, navigate to the ios directory and run pod install.

Terminal window
cd apps/<path-to-app>/mobile/ios/
pod install

After these steps are complete, the app should build and run successfully.