Skip to main content

How to add code to native using expo-bare-react-native-app

For situations where you need to verify the generated platform files, the expo-bare-react-native-app repository is available. This repository can be used to test builds and confirm that app configurations are functioning as expected.

Get Started

  1. Clone the expo-bare-react-native-app repository

  2. Install all dependencies using yarn install

  3. Add your plugin to packages/plugins directory

  4. Create an app.plugin.js file at the root of your plugin with the following content:

    module.exports = function customExportFunction(config) {
    return config;
    };
  5. Update the expo_plugins array in appmaker.package.plugin.json to include the path to your plugin's app.plugin.js file:

    {
    "expo_plugins": [
    "@appmaker-xyz/plugins/my-plugin-1/app.plugin.js",
    "@appmaker-xyz/plugins/my-plugin-2/app.plugin.js",
    "@appmaker-xyz/plugins/my-plugin-2/app.plugin.js",
    ]
    }
  6. Run expo prebuild to generate platform files with your custom configuration

After completing these steps, you should be able to see your custom configuration within the generated platform files.

Configuring platform files

Under the hood, this is using expo-config-plugins to generate the paltform files. You can learn more about it here

For Android (build.gradle)

To add a new implementation in the build.gradle file, you can modify your app.plugin.js file as follows:

const { withAppBuildGradle } = require('@expo/config-plugins');
const PATH_TO_ADD = `implementation("com.facebook.react:react-android")`;
const withCustomAppBuildGradleImplementation = (
config,
{ implementationPackage },
) => {
return withAppBuildGradle(config, (config) => {
if (config.modResults.contents.includes(implementationPackage)) {
return config;
}
config.modResults.contents = config.modResults.contents.replace(
PATH_TO_ADD,
`${PATH_TO_ADD}
${implementationPackage}`,
);
return config;
});
};

module.exports = function withCustom(config) {
config = withCustomAppBuildGradleImplementation(config, {
implementationPackage: 'implementation("com.custom:app-android-sdk:12.5.06")',
});
return config;
};

How it works

  • The code first checks if the specified implementation is already present in the build.gradle file.
  • If the implementation is not found, it adds the new implementation to the file.
  • It uses the withAppBuildGradle method to modify the build.gradle file.
  • Inside the withAppBuildGradle method, it locates the string implementation("com.facebook.react:react-android") and adds the new implementation directly below it.

This approach ensures that your custom implementation is added to the build.gradle file without duplicating existing entries, and places it in a specific location within the file.

For iOS (Info.plist)

To add new entries in the Info.plist file, you can modify your app.plugin.js file as follows:

const { withInfoPlist } = require('expo/config-plugins');

module.exports = function myCustomExpoFunctionName(config) {
config = withInfoPlist(config, (config) => {
// Type 1: Adding a String
config.modResults['YourCustomMessageKey'] = 'Your custom message';

// Type 2: Adding a Dictionary
config.modResults.MyCustomDictionary = {
MY_FIRST_KEY: 'My first value',
MY_SECOND_KEY: 'My second value'
};

// Type 3: Adding an Array
config.modResults.MyCustomArray = ['My first value', 'My second value'];

return config;
});
return config;
};

How it works

  • The code uses the withInfoPlist method from Expo's config plugins to modify the Info.plist file.
  • It demonstrates three types of modifications: adding a string, a dictionary, and an array.
  • For each type, it directly modifies the config.modResults object, which represents the contents of the Info.plist file.
  • The changes are applied without checking for existing entries, so be cautious to avoid overwriting important existing configurations.

Modifying MainApplication.java and AppDelegate.m

You can find the guides for injecting code into AppDelegate.m and MainApplication.java.