## Check if the resources are downloaded

JavaScript

```javascript
IncodeSdk.checkOnDemandResourcesDownloaded()
		.then((result) => {
			console.log('resourcesAvailable: ', result.status);
			// if status is 'true' resources are available, otherwise 'false' and they need to be downloaded
		})
		.catch((e) => {
			//
		});
```

## Download resources

Download of the resources is done using following method:

JavaScript

```javascript
IncodeSdk.downloadOnDemandResources()
		.then((result) => {
			console.log('downloadCompleted, status: ', result.status);
			// if status is 'success' resources are downloaded, otherwise download has to be retried
		})
		.catch((e) => {
			// Check for specific error values and try retrying the download
		});
```

It downloads the resources silently in the background. To be notified about the download progress:

JavaScript

```javascript
IncodeSdk.onResourceDownloadProgressUpdated((progress) => {
		console.log(‘download progress updated: ’, progress); // progress value ranges from 0 - 1.
	});
```

List of error codes for `downloadOnDemandResources` method:

- `INTERNAL_ERROR` - unknown error, please contact Incode to resolve the issue and provide the error code.
- `NETWORK_ERROR` - The download request failed because of a network error, retry again later
- `ACCESS_DENIED` - The app is unable to register the request because of insufficient permissions, retry after user accepts the permissions

## Remove resources

Once you no longer need Incode SDK you might notify the system that the download resources are no longer needed, and they will be removed as soon as possible.

JavaScript

```javascript
IncodeSdk.removeOnDemandResources()
        .then(() => {
          console.log("removeOnDemandResources result: ", result.status);
          //if status is 'success' system is notified that resources are no longer needed and will remove them as soon as possible
        })
        .catch( (e) => {
          //
        });
```

## Additional iOS setup

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

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

After doing the `pod install` now, the Dynamic delivery version will be used and the resources won't be embedded in the app, but you would have to download them using the method mentioned in `Download Resources` section.

## Additional Android setup

You need to be using Android App Bundle format when publishing your app.

Dynamic Feature Modules are supported on devices running Android 5.0 (API level 21) or higher.

That means that on other devices, dynamic modules will be installed together with the app.

### Step 1

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

Gradle

```groovy
compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}
```

### Step 2

In your application `Application` class, make it extend `SplitCompatApplication`

Java

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

public class BaseApplication extends SplitCompatApplication {
    ...
}
```

SplitCompatApplication simply 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, as follows:

Java

```java
@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 set to 21 or higher, MultiDex is enabled by default and you can skip this step.

If your `minSdkVersion` is lower than 21, follow this guide from Google to enable MultiDex:

[https://developer.android.com/studio/build/multidex#mdex-gradle](https://developer.android.com/studio/build/multidex#mdex-gradle)

### Step 4

Create new Dynamic Module in Android Studio:

- `File` --> `New` --> `New Module`
- Select `Dynamic Feature Module`

Click `Next`

- Enter `Module name`, for example: `incode_core`

Click `Next`

- Set your desired `Module Title`, for example: `Incode Core`

Set `Install-time inclusion` to `Do not include module at install-time (on-demand only)`

Enable `Fusing`

- Click `Finish` to create the Dynamic Module.

###### Note: Incode SDK uses `incode_core` as the default name of the on-demand module. If you provide a module name different than `incode_core` in this step make sure to override the default `moduleName` parameter with the same value when you call `downloadOnDemandResources` API.

JavaScript

```javascript
IncodeSdk.downloadOnDemandResources({moduleName: 'MyCustomModuleName'})
        .then((result) => {
            console.log('downloadCompleted, status: ', result.status);
            // if status is 'success' resources are downloaded, otherwise download has to be retried
        })
        .catch((e) => {
            // Check for specific error values and try retrying the download
        });
```

### Step 5

Wait for Android Studio to finish syncing.

After the process is complete, take some time to review the changes that have been made to the project by Android Studio:

- You have a new module named `incode_core`
- In your module-level `app/build.gradle`, the following line has been added to `android{}` closure:

```undefined
dynamicFeatures = [':incode_core']
```
- In your `app/res/values/strings.xml` file, a string has been added:

```xml
<string name="title_incode_core">Incode Core</string>
```

### Step 6

Open `incode_core/build.gradle`

Add the following code to `android{}` closure:

Gradle

```groovy
compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
}
```

Add the following dependency:

Gradle

```groovy
implementation 'com.incode.sdk:core-light:2.0.0' // Required core dependency
```

The `incode_core` module does not need to contain any other code.

Required `core-light` dependency contains the image processing libraries that are used in the Welcome SDK.

### Step 7

Enable splits - optimized APKs for each user’s device configuration. If your app is using App Signing by Google Play you can skip this step because splits are enabled by default. Check [https://reactnative.dev/docs/signed-apk-android#migrating-old-android-react-native-apps-to-use-app-signing-by-google-play](https://reactnative.dev/docs/signed-apk-android#migrating-old-android-react-native-apps-to-use-app-signing-by-google-play) and [https://developer.android.com/studio/build/configure-apk-splits](https://developer.android.com/studio/build/configure-apk-splits) for more information.

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

Gradle

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

Gradle configuration is done!

### Step 8 - Testing your implementation

If you now try to run your application from Android Studio, the Dynamic Module will be installed together with the app,

and the code for downloading and installing the module will never execute.

To locally simulate requesting, downloading, and installing modules from the Play Store use the bundletool. Download and install bundletool from [https://github.com/google/bundletool/releases](https://github.com/google/bundletool/releases)

Use the following commands to build and install an apk for local test:

```undefined
./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
```

To actually test your implementation (downloading and installing the Dynamic Module),

you need to upload your App Bundle to Google Play.

To support on demand modules, Google Play requires that you upload your application using the Android App Bundle format so that it can handle the on demand requests from the server side.

Publishing the project on the Play Console requires some graphic assets,

so for testing purposes you can use these sample assets from the Google codelab:

[https://github.com/googlecodelabs/android-dynamic-features/tree/master/graphic_assets](https://github.com/googlecodelabs/android-dynamic-features/tree/master/graphic_assets)

To be able to quickly test your application, without waiting for any approval, you can publish your application in the Internal Testing track.

For a step by step guide on how to publish a new application on the Google Play Store, you can follow the [Play Console Guide on how to upload an app](https://support.google.com/googleplay/android-developer/answer/9859152)
