# Configure the SDK

The configuration process of the SDK has severable responsibilities when configured through SDK key:

* Validation of the license key
* Validating the currently present files
* Downloading or updating the files required by the SDK to do recognition
* Preparing the files to be used for inference

The SDK is configured using a `PassioConfiguration` object. This object is used to define the location of the files that the SDK requires.&#x20;

{% hint style="info" %}
When the SDK is configured without SDK key (using Proxy URL), the SDK will be `remoteOnly`. More information on this flag is described in below section.
{% endhint %}

### SDK downloads the models

The default behaviour (or by setting the _sdkDownloadsModels_ field to true) of the SDK is to download the required files for [local recognition](https://passio.gitbook.io/nutrition-ai/guides/nutrition-ai-sdk/use-cases/food-recognition#local-neural-network-model). If the current files that are present on the device are older than the version of the SDK library, the SDK will download the newer version in the background, but still run the session with the older version of the files. Once the download is finished, the new files will be applied on the next session. Don't forget to add the import statement for the nutrition sdk.

The SDK will not download required files for [local recognition](https://passio.gitbook.io/nutrition-ai/guides/nutrition-ai-sdk/use-cases/food-recognition#local-neural-network-model) when configured without SDK key. The SDK will be in `remoteOnly` mode.

{% tabs %}
{% tab title="iOS" %}
```swift
import PassioNutritionAISDK
import AVFoundation

...

let passioSDK = PassioNutritionAI.shared

override func viewDidLoad() {
    super.viewDidLoad()
    configureSDK()
}

// Configuring SDK using SDK key

func configureSDK() {
    let key = "YOUR_PASSIO_KEY"
    let passioConfig = PassioConfiguration(key: key)
    
    passioSDK.configure(passioConfiguration: passioConfig) { (status) in
        print("Mode = \(status.mode)\n missingfiles = \(String(describing: status.missingFiles))" )
    }
}

// Configuring SDK using Proxy

func configureSDK() {
    var passioConfig = PassioConfiguration()
    // Set the base URL of the target proxy endpoint
    passioConfig.proxyUrl = "https://yourdomain.com/nutrition/"
    // Set headers as per your requirements
    passioConfig.proxyHeaders = ["header" : "value"] 
    
    passioSDK.configure(passioConfiguration: passioConfig) { (status) in
        print("Mode = \(status.mode)\n missingfiles = \(String(describing: status.missingFiles))" )
    }
}
```
{% endtab %}

{% tab title="Android" %}
```kotlin
val passioConfiguration = PassioConfiguration(
    this.applicationContext,
    "Your license key here"
).apply {
    sdkDownloadsModels = true // This can be ommited
}

PassioSDK.instance.configure(passioConfiguration) { passioStatus ->
    // Handle PassioStatus states
} 
```
{% endtab %}

{% tab title="React Native" %}
```typescript
const [isReady, setIsReady] = useState(false);

// Effect to configure the SDK and request camera permission
// We are adding our developer key in LoadingContainerView
useEffect(() => {
  Promise.all([
    PassioSDK.configure({
      key: 'your-developer-key',
      autoUpdate: true,
    }),
    PassioSDK.requestCameraAuthorization(),
  ]).then(([sdkStatus, cameraAuthorized]) => {
    setIsReady(sdkStatus.mode === 'isReadyForDetection' && cameraAuthorized);
  });
}, []);
```
{% endtab %}

{% tab title="Flutter" %}
```dart
import 'package:nutrition_ai/nutrition_ai_sdk.dart';

void configureSDK() async {
   String passioKey = "Your_PassioSDK_Key";
   var configuration = PassioConfiguration(passioKey);
   passioStatus = await NutritionAI.instance.configureSDK(configuration);
   // Handle result of the configuration process.
}
```
{% endtab %}
{% endtabs %}

### Remote Only configuration

The models required for the SDK to run local recognition can take some time for the first download. If the local recognition is not needed, setting the `remoteOnly` to true on the PassioConfiguration process will skip the download of the models. Remote recognition functions like _recognizeImageRemote_ or _searchForFood_ will still work.&#x20;

{% hint style="danger" %}
If `remoteOnly` is used when configuring the SDK, calling [startFoodDetection](https://passio.gitbook.io/nutrition-ai/guides/nutrition-ai-sdk/use-cases/food-recognition#start-food-detection) with visual or packaged food detection enabled will have no effect. &#x20;
{% endhint %}

### Handling the configure status object

The result of the configuration process is a `PassioStatus` object, containing a PassioMode attribute along with the missingFiles, debugMessage, error object and the active models number. The attribute that needs to looked at is the mode.

`PassioMode` is an enum describing the current state of the Passio SDK configuration process:

* **notReady** -> The configuration process hasn't started yet.
* **failedToConfigure** -> There was an error during the configuration process.
* **isBeingConfigured** -> The SDK is still in the configuration process. Normally, you shouldn't receive this mode as a callback to the configure method. If you do please contact our support team.
* **isDownloadingModels** -> The files required by the SDK to work are not present and are currently being downloaded.
* **isReadyForDetection** -> The SDK is configured with the set of files defined by the activeModels attribute.

The _missingFiles_ variable contains a list of all the files missing for the SDK to work **optimally**. When this list is not null, this doesn't mean that the SDK is not operational. The SDK may be initialized with older files, but it will advocate the download of the newest files through this list.

The _debugMessage_ usually gives more verbose and human-readable information about the configuration process. It will always give an error message if the mode is FAILED\_TO\_CONFIGURE.

The _activeModels_ will give the version of the files installed and ran by the SDK if the configuration process ran successfully i.e. if the mode is IS\_READY\_FOR\_DETECTION.

### Proxy url and headers

There are cases when the implementing app wants to redirect all of the networking calls from the SDK to their backend first, before relaying the requests to Passio's backend. In this case, the app's backend acts like a proxy between the SDK and it's backend. To achieve this behaviour, the SDK offers two parameters in the _PassioConfiguration_ object: `proxyUrl` and `proxyHeaders`.

{% hint style="info" %}
If supplied, the SDK will use the `proxyUrl` value as a base url when executing networking calls, and will append the provided `proxyHeaders` to the request itself. When proxyUrl is provided, the SDK operates in _remoteOnly_ state.
{% endhint %}

### Best practices

1. Make sure there is internet connection for the configuration process. The SDK needs to download the license file and the required files. If there is no internet connection the configuration status mode will be failedToConfigure.
2. The PassioStatus mode is notReady -> check debugMessage for the error, usually the wrong license key has been supplied or the files are missing.
3. The PassioStatus mode is isDownloadingModels -> register a `PassioStatusListener` through the setPassioStatusListener method as it will enable tracking of the download progress.
4. The PassioStatus mode is isReadyForDetection -> still check the missingFiles because the SDK might be running with an older version of the files and newer need to be downloaded.
