SDK reference · React Native SDK / React Native Getting Started

Dynamic Delivery Usage Guide

To reduce your app's download size and the SDK's storage footprint, you can download additional SDK resources on demand during your app's execution rather than bundling them at install time. The React Native SDK provides methods to:

  • Check whether the resources are downloaded
  • Download them if they aren't
  • Remove them when you no longer need the SDK's features

Check if the resources are downloaded

Before running a flow that needs on-demand resources, check whether they are already present on the device. Call checkOnDemandResourcesDownloaded(), which resolves with a status.

IncodeSdk.checkOnDemandResourcesDownloaded()
  .then((result) => {
    console.log('resourcesAvailable: ', result.status);
  })
  .catch((e) => {
    //
  });

If status is true, the resources are available and you can proceed. If status is false, the resources need to be downloaded (see Download resources).

Download resources

Download the resources with downloadOnDemandResources(). The download runs silently in the background and resolves with a status when complete.

IncodeSdk.downloadOnDemandResources()
  .then((result) => {
    console.log('downloadCompleted, status: ', result.status);
  })
  .catch((e) => {
    // Check the error code and retry the download if appropriate.
  });

If status is success, the resources have been downloaded. Otherwise, the download should be retried.

To be notified of download progress, register a progress listener. The progress value ranges from 0 to 1.

IncodeSdk.onResourceDownloadProgressUpdated(({ progress }) => {
  console.log('download progress updated: ', progress);
});

downloadOnDemandResources() can fail with the following error codes:

  • INTERNAL_ERROR: An unknown error occurred. Contact your Incode representative with the error code to resolve the issue.
  • NETWORK_ERROR: The download request failed because of a network error. Retry later.
  • ACCESS_DENIED: The app could not register the request because of insufficient permissions. Retry after the user accepts the permissions.

❗{/* [SME input needed: these error codes use SCREAMING_SNAKE_CASE unlike other React Native SDK error codes which use camelCase. Since developers match against these exact strings when handling errors, I wanted to confirm the precise casing for each. Escalation candidate: needs product/SDK-team knowledge.] */}

Remove resources

When you no longer need the Incode SDK, you can notify the system that the downloaded resources are no longer needed. They will be removed as soon as possible.

IncodeSdk.removeOnDemandResources()
  .then((result) => {
    console.log('removeOnDemandResources result: ', result.status);
  })
  .catch((e) => {
    //
  });

If status is success, the system has been notified and will remove the resources as soon as possible.

Additional iOS setup

To use Dynamic Delivery in your iOS app, add this line to the top of the Podfile for your target:

pod 'react-native-incode-sdk/ODR', :path => '../node_modules/react-native-incode-sdk/ios'

After you run pod install, the SDK uses the Dynamic Delivery version and the resources are no longer embedded in the app. You will need to download them using the method described in Download resources.

Additional Android setup

You must publish your app using the Android App Bundle format. Dynamic Feature Modules are supported on devices running Android 5.0 (API level 21) or higher. On older devices, dynamic modules are installed together with the app.

Step 1: Set Java compatibility

In your module-level app/build.gradle, add the following to the android {} closure:

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}

Step 2: Extend SplitCompatApplication

Make your Application class extend SplitCompatApplication:

import com.google.android.play.core.splitcompat.SplitCompatApplication;

public class BaseApplication extends SplitCompatApplication {
    ...
}

SplitCompatApplication overrides ContextWrapper.attachBaseContext() to include SplitCompat.install(Context applicationContext). If you don't want your Application class to extend SplitCompatApplication, you can override the attachBaseContext() method manually:

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    // Emulates installation of future on-demand modules using SplitCompat.
    SplitCompat.install(this);
}

Step 3: Enable MultiDex

If your minSdkVersion is 21 or higher, MultiDex is enabled by default and you can skip this step.

If your minSdkVersion is lower than 21, follow Google's guide to enable MultiDex.

Step 4: Create a dynamic feature module

Create a new dynamic feature module in Android Studio:

  1. Go to File > New > New Module.
  2. Select Dynamic Feature Module, then click Next.
  3. Enter a Module name, for example incode_core, then click Next.
  4. Enter your desired Module Title, for example Incode Core. Set Install-time inclusion to Do not include module at install-time (on-demand only), and enable Fusing.
  5. Click Finish to create the module.

Info

Note

The Incode SDK uses incode_core as the default name of the on-demand module. If you use a different module name in this step, override the default moduleName parameter with the same value when you call downloadOnDemandResources():

IncodeSdk.downloadOnDemandResources({ moduleName: 'MyCustomModuleName' })
  .then((result) => {
    console.log('downloadCompleted, status: ', result.status);
  })
  .catch((e) => {
    // Check the error code and retry the download if appropriate.
  });

Step 5: Review the generated changes

Wait for Android Studio to finish syncing. Once it completes, review the changes Android Studio made to the project:

  • A new module has been created with the name you chose in Step 4 (for example, incode_core).
  • In your module-level app/build.gradle, the following line has been added to the android {} closure (using your module name):
  dynamicFeatures = [':incode_core']
  • In your app/res/values/strings.xml file, a string has been added:
  <string name="title_incode_core">Incode Core</string>

Step 6: Configure the module's build.gradle

Open the build.gradle for your module (for example, incode_core/build.gradle).

Add the following to the android {} closure:

compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}

Add the required core dependency:

implementation 'com.incode.sdk:core-light:2.0.0'

The module does not need to contain any other code. The core-light dependency contains the image processing libraries used by the native Android Welcome SDK.

Step 7: Enable APK splits

Enable splits to generate optimized APKs for each user's device configuration. If your app uses App Signing by Google Play, you can skip this step, since splits are enabled by default.

In your module-level app/build.gradle, add the following to the android {} closure:

splits {
    abi {
        reset()
        enable true
        universalApk false  // If true, also generate a universal APK
        include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
    }
}

For more information, see App Signing by Google Play in React Native's developer documentation and Configure APK splits in Android's developer documentation.

Step 8: Test your implementation

If you run your app from Android Studio, the dynamic module is installed together with the app, and the code for downloading and installing the module never executes. To test the download and install flow, you need to simulate or use the Play Store.

Local testing

To locally simulate requesting, downloading, and installing modules from the Play Store, use bundletool. Download and install it from the bundletool releases page.

Use the following commands to build and install an APK for local testing:

./gradlew bundle

bundletool build-apks --local-testing \
  --bundle app/build/outputs/bundle/release/app-release.aab \
  --output my_app.apks

bundletool install-apks --apks my_app.apks

Testing through Google Play

To fully test your implementation (downloading and installing the dynamic module), upload your App Bundle to Google Play. Google Play requires the Android App Bundle format so it can handle on-demand requests from the server side.

Publishing on the Play Console requires some graphic assets. For testing purposes, you can use the sample assets from the Google codelab.

To test quickly without waiting for approval, publish your application to the Internal Testing track. For a step-by-step guide, see how to upload an app in the Play Console documentation.

Was this page helpful?