> For the complete documentation index, see [llms.txt](https://legacy-docs.usesmileid.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://legacy-docs.usesmileid.com/integration-options/mobile/getting-started.md).

# Getting Started

## Requirements

{% tabs %}
{% tab title="Android" %}

* Android 5.0+ (API level 21+)
* A `smile_config.json` file from your portal [Security Settings](https://portal.usesmileid.com/security-settings) page
* [A device with Google Play Services](#user-content-fn-1)[^1]
  {% endtab %}

{% tab title="iOS" %}

* iOS 13+
* Xcode 14+
* A `smile_config.json` file form your portal [Security Settings](https://portal.usesmileid.com/security-settings) page
  {% endtab %}

{% tab title="Flutter" %}

* Flutter 3.0.0+
* Dart 3.0.5+
* Android 5.0+ (API level 21+)
* iOS 13.0+
* A `smile_config.json` file from your portal [Security Settings](https://portal.usesmileid.com/security-settings) page
* A device with Google Play Services
  {% endtab %}

{% tab title="React Native" %}

* React Native 0.70.+
* Android 5.0+ (API level 21+)
* iOS 13.0+
* A `smile_config.json` file from your portal [Security Settings](https://portal.usesmileid.com/security-settings) page
* [A device with Google Play Services](#user-content-fn-1)
  {% endtab %}

{% tab title="React Native Expo" %}

* React Native 0.79.1+
* Expo 53.0.0+
* Android 5.0+ (API level 21+)
* iOS 13.0+
* A `smile_config.json` file from your portal [Security Settings](https://portal.usesmileid.com/security-settings) page
* [A device with Google Play Services](#user-content-fn-1)
  {% endtab %}
  {% endtabs %}

## SDK Versions

We’re excited to share that our mobile SDKs have been upgraded from **v10** to **v11**, bringing you enhanced functionality while maintaining full backward compatibility. These non-breaking updates ensure a smooth transition by simply updating to v11 to access the latest features without altering your existing integration.

> **Note:** For native Android, please use **version 11.0.2 or later** to guarantee optimal performance.

For complete details, including bug fixes and new capabilities, please refer to our [release notes](/integration-options/mobile/release-notes.md).

For lifecycle expectations, support windows, and upgrade policy, see the [Mobile SDK Versioning and Support Policy](/further-reading/versioning-and-support-policy.md).

## Dependency

{% tabs %}
{% tab title="Android" %}
[![Maven Central](https://img.shields.io/maven-central/v/com.smileidentity/android-sdk)](https://mvnrepository.com/artifact/com.smileidentity/android-sdk)

The latest release is available on [Maven Central](https://central.sonatype.com/artifact/com.smileidentity/android-sdk/versions) and on [GitHub](https://github.com/smileidentity/android/releases).

Snapshot builds are also [available](https://oss.sonatype.org/content/repositories/snapshots/com/smileidentity/android-sdk/).

Add the dependency to your module-level Gradle Build file

{% tabs %}
{% tab title="build.gradle.kts (Kotlin DSL)" %}

```kotlin
implementation("com.smileidentity:android-sdk:<latest-version>")
```

{% endtab %}

{% tab title="build.gradle (Groovy)" %}

```groovy
implementation "com.smileidentity:android-sdk:<latest-version>"
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Proguard rules are shipped with the SDK

If you use **Dexguard**, add the following rule

```
-encryptassetfiles assets/io/*, assets/dexopt/*, assets/smile_config.json
```

{% endhint %}
{% endtab %}

{% tab title="iOS" %}
{% tabs %}
{% tab title="Swift Package Manager" %}

1. In Xcode, select **File** > **Add Packages…** and enter <https://github.com/smileidentity/ios>
2. Select the latest version number from our release page and click add package
   {% endtab %}

{% tab title="CocoaPods" %}

* If you haven’t already, install the latest version of [CocoaPods](https://guides.cocoapods.org/using/getting-started.html).
* If you don’t have an existing [Podfile](https://guides.cocoapods.org/syntax/podfile.html), run the following command to create one:

```shell-session
$ pod init
```

* Add this line to your `Podfile`:

```
pod 'SmileID'
```

* Run the following command:

```shell-session
$ pod install
```

* Make sure to use the `.xcworkspace` file to open your project in Xcode, instead of the `.xcodeproj` file subsequently
  {% endtab %}
  {% endtabs %}
  {% endtab %}

{% tab title="Flutter" %}
The latest release is available on [pub.dev](https://pub.dev/packages/smile_id)

Add the dependency to your `pubspec.yaml`

```yaml
dependencies:
  smile_id: <latest-version>
```

If you're using Kotlin < 2.0.0, you need to manually specify your Kotlin and Compose compiler versions. Set them in your project-level `build.gradle.kts` file like this:

```
extra.set("kotlinVersion", "1.9.25")
extra.set("kotlinCompilerExtensionVersion", "1.5.15")
```

{% hint style="warning" %}
:warning: Note the `Compose to Kotlin Compatibility Map` here - <https://developer.android.com/jetpack/androidx/releases/compose-kotlin>
{% endhint %}
{% endtab %}

{% tab title="React Native" %}
The latest release is available on [npm](https://www.npmjs.com/package/@smile_identity/react-native)

Add the dependency to your package.json

```
"dependencies" : {
 "@smile_identity/react-native": "<version>"
}
```

If you are using Kotlin <2.0.0 and you need to specify your Kotlin/Compose versions, you should set it up like this in the `buildscript` block of your `android/build.gradle` file

```groovy
buildscript {
  ext {
    buildToolsVersion = "34.0.0"
    minSdkVersion = 23
    compileSdkVersion = 35
    targetSdkVersion = 35
    kotlinVersion = "1.9.24"
    kotlinCompilerExtensionVersion = "1.5.14"
    
    ndkVersion = "26.1.10909125"
  }
...
...
}
```

{% hint style="warning" %}
:warning: Note the `Compose to Kotlin Compatibility Map` here - <https://developer.android.com/jetpack/androidx/releases/compose-kotlin>
{% endhint %}

If you run into build issues related to Jetpack Compose, you may need to also update your application `build.gradle` file to enable Compose and specify the Compose Compiler version. See here for additional details: <https://developer.android.com/jetpack/androidx/releases/compose-kotlin>

```gradle
android {
    buildFeatures {
        compose true
    }
    composeOptions {
        kotlinCompilerVersion = "" // Specify the version compatible with your project's Kotlin version
    }
    kotlinOptions {
        freeCompilerArgs += ['-Xskip-metadata-version-check'] // only add if kotlin version is before 2.0
    }
}
```

{% hint style="info" %}
:warning: **Note:** If you are using any kotlin version before 2.0, please add this `freeCompilerArgs += ['-Xskip-metadata-version-check']` as shown in the configuration above.
{% endhint %}
{% endtab %}

{% tab title="React Native Expo" %}
The latest release is available on [npm](https://www.npmjs.com/package/@smile_identity/react-native-expo)

Add the dependency to your package.json

```
"dependencies" : {
 "@smile_identity/react-native-expo": "<version>"
}
```

{% endtab %}
{% endtabs %}

## Smile Config

{% tabs %}
{% tab title="Android" %}
Place the `smile_config.json` file under your application's assets, located at `src/main/assets` (This should be at the same level as your `java` and `res` directories)

{% hint style="warning" %}
:warning: **Note:** The `smile_config.json` file is unique to the environment (sandbox/production) and api key for which it was created. This means you will need one file for each environment (sandbox/production) of your application.
{% endhint %}

{% hint style="info" %}
:warning: **Note:** You may need to create this directory if it does not already exist
{% endhint %}
{% endtab %}

{% tab title="iOS" %}
Drag the `smile_config.json` file into your projects file inspector and ensure that the file is added to your app's target. Confirm that it is by checking the Copy Bundle Resources drop down in the Build Phases tab as shown below.

<figure><img src="/files/g5wk6XFy0eJvrfXISqj9" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
:warning: **Note:** The `smile_config.json` file is unique to the environment (sandbox/production) and api key for which it was created. This means you will need one file for each environment (sandbox/production) of your application.
{% endhint %}
{% endtab %}

{% tab title="Flutter" %}
The `smile_config.json` file contains parameters required for you application to connect to Smile ID. You will use the contents during the initialization (next section) of the Smile ID SDK.

You can download this file from your [Smile ID portal account](https://portal.usesmileid.com/security-settings).

{% hint style="warning" %}
:warning: **Note:** The `smile_config.json` file is unique to the environment (sandbox/production) and api key for which it was created. This means you will need one file for each environment (sandbox/production) of your application.
{% endhint %}

If you run into build issues related to Jetpack Compose, you may need to also update your application `build.gradle` file to enable Compose and specify the Compose Compiler version. See here for additional details: <https://developer.android.com/jetpack/androidx/releases/compose-kotlin>

```gradle
android {
    buildFeatures {
        compose true
    }
    composeOptions {
        kotlinCompilerVersion = "" // Specify the version compatible with your project's Kotlin version
    }
    kotlinOptions {
        freeCompilerArgs += ['-Xskip-metadata-version-check'] // only add if kotlin version is before 2.0
    }
}
```

{% hint style="info" %}
:warning: **Note:** If you are using any kotlin version before 2.0, please add this `freeCompilerArgs += ['-Xskip-metadata-version-check']` as shown in the configuration above.
{% endhint %}

**FlutterFragmentActivity**

Be sure to update your `MainActivity.kt` (android/app/src/main/kotlin//MainActivity.kt) like below:

```kotlin
import io.flutter.embedding.android.FlutterFragmentActivity

class MainActivity : FlutterFragmentActivity() {}
```

{% endtab %}

{% tab title="React Native" %}
The `smile_config.json` file contains parameters required for you application to connect to Smile ID. You will use the contents during the initialization (next section) of the Smile ID SDK.

You can download this file from your [Smile ID portal account](https://portal.usesmileid.com/security-settings).

{% hint style="warning" %}
:warning: **Note:** The `smile_config.json` file is unique to the environment (sandbox/production) and api key for which it was created. This means you will need one file for each environment (sandbox/production) of your application.
{% endhint %}
{% endtab %}

{% tab title="React Native Expo" %}
The `smile_config.json` file contains parameters required for you application to connect to Smile ID. You will use the contents during the initialization (next section) of the Smile ID SDK.

You can download this file from your [Smile ID portal account](https://portal.usesmileid.com/security-settings).

{% hint style="warning" %}
:warning: **Note:** The `smile_config.json` file is unique to the environment (sandbox/production) and api key for which it was created. This means you will need one file for each environment (sandbox/production) of your application.
{% endhint %}
{% endtab %}
{% endtabs %}

## Initialization

{% tabs %}
{% tab title="Android" %}
Initialize the Smile ID SDK in your `Application` class `onCreate`

{% hint style="info" %}
You may need to create an `Application` class for your app, if one doesn't already exist
{% endhint %}

{% hint style="warning" %}
:warning: **Note:** The `SmileID.initialize()` method now returns a deferred result. You can use you can use the `isSuccess` and `isFailure` properties of `Result`. An exception is thrown if MLKit initialization fails. You will need to handle this exception in your application.

See the guide [here](https://developers.google.com/ml-kit/vision/face-detection/android) to use the bundled version which fixes the exception.
{% endhint %}

{% tabs %}
{% tab title="Kotlin" %}
{% code title="ExampleApplication.kt" %}

```kotlin
package com.example.app

import android.app.Application
import com.smileidentity.SmileID

class ExampleApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        SmileID.initialize(this)
    }
}
```

{% endcode %}
{% endtab %}

{% tab title="Java" %}
{% code title="ExampleApplication.java" %}

```java
package com.example.app;

import android.app.Application;
import com.smileidentity.SmileID;

public class ExampleApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        SmileID.initialize(this);
    }
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

**With API Key**

```kotlin
SmileID.initialize(
    apiKey = "your-api-key",
    context = this,
)
```

{% hint style="warning" %}
Treat your API key like a secret. Don't commit it to source control or ship it in plain text in your app — use a secure secret store or inject it at build time.
{% endhint %}
{% endtab %}

{% tab title="iOS" %}
Initialize the SDK as early as possible. This can be done either in your AppDelegate's `application(_:didFinishLaunchingWithOptions:)` method or the SceneDelegate `scene(_:willConnectTo:options:)` depending on your app's structure.

{% code title="AppDelegate.swift" %}

```swift
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication,
                     didFinishLaunchingWithOptions
                     launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        let config = try? Config(url: Constant.configUrl)
        SmileID.initialize(config: config)
        return true
    }
}
```

{% endcode %}

**With API Key**

```swift
SmileID.initialize(apiKey: "your-api-key")
```

{% hint style="warning" %}
Treat your API key like a secret. Don't commit it to source control or ship it in plain text in your app — use a secure secret store or inject it at build time.
{% endhint %}
{% endtab %}

{% tab title="Flutter" %}
Initialize the Smile ID SDK in `main.dart` by calling `initializeWithConfig`

```dart
import 'package:smile_id/smile_id.dart';
//the values should be passed in as secrets taken from your smile_config.json file
void main()  {
  SmileID.initializeWithConfig(
      useSandbox: false,
    config: FlutterConfig(
        partnerId: partnerId,
        authToken: authToken,
        prodBaseUrl: prodBaseUrl,
        sandboxBaseUrl: sandboxBaseUrl
    ),
    enableCrashReporting: false
  );
}
```

**With API Key**

```dart
SmileID.initializeWithApiKey(
    apiKey: "your-api-key",
    config: FlutterConfig(
        partnerId: partnerId,
        authToken: authToken,
        prodBaseUrl: prodBaseUrl,
        sandboxBaseUrl: sandboxBaseUrl,
    ),
    useSandbox: false,
    enableCrashReporting: false,
);
```

{% hint style="warning" %}
Treat your API key like a secret. Don't commit it to source control or ship it in plain text in your app — use a secure secret store or inject it at build time.
{% endhint %}

{% hint style="warning" %}
On Android, your Activity must inherit from `FlutterFragmentActivity` instead of `FlutterActivity`
{% endhint %}
{% endtab %}

{% tab title="React Native" %}
Initialize the Smile ID SDK in your app entry point, typically `App.tsx` by calling `initialize method`

```typescript
/**
 * Initialize SmileID SDK with configuration
 * @param useSandBox - true for sandbox environment, false for production
 * @param enableCrashReporting - Whether to enable crash reporting
 * @param config - Configuration object for the SDK
 * @param apiKey - API key specific to the partner and environment
 */
initialize: (
  useSandBox: boolean = false,
  enableCrashReporting: boolean = false,
  config?: Config,
  apiKey?: string,
) => _SmileID.initialize(useSandBox, enableCrashReporting, config, apiKey),
```

```typescript
import { SmileID } from "@smile_identity/react-native";

//You would use the same config object this comes from the 
//smile id portal as the smile_config.json and you can copy paste contents to this
//object
const config: Config = {
  partnerId: 'YOUR PARTNER ID',
  authToken: 'YOUR AUTH TOKEN',
  prodLambdaUrl: 'PROD LAMBDA URL',
  testLambdaUrl: 'TEST LAMBDA URL',
};
/* Option 1
This requires using the config
*/
React.useEffect(() => {
  SmileID.initialize(true,true,config); 
}, []);

/* Option 2
This requires using the api key
*/
React.useEffect(() => {
  SmileID.initialize(true,true,config,'YOUR API KEY'); 
}, []);
```

{% endtab %}

{% tab title="React Native Expo" %}
Initialize the Smile ID SDK in your app entry point by calling `initialize` method

```typescript
  /**
   * Initialize SmileID SDK with configuration
   * @param useSandBox - Configuration object for the SDK
   * @param enableCrashReporting - Whether to enable crash reporting
   * @param config - Configuration object for the SDK
   * @param apiKey - api key specific to the partner and also environment
   */
  initialize(
      useSandBox: boolean,
      enableCrashReporting: boolean,
      config?: SmileConfig,
      apiKey?: string,
  ): Promise<void>;
```

The Smile ID Expo SDK offers three flexible initialization methods to suit different development needs.

```typescript
import { initialize, SmileConfig } from '@smile_identity/react-native-expo';
```

**Option 1: Programmatic Configuration**

```typescript
// Create configuration object with your Smile ID portal credentials
const config = new SmileConfig(
  'your_partner_id',              // Partner ID from Smile ID portal
  'your_auth_token',              // Authentication token
  'https://prod-lambda-url.com',  // Production lambda URL
  'https://test-lambda-url.com'   // Test lambda URL
);

// Initialize with configuration object
initialize(true, true, config);
```

**Option 2: Configuration with API Key**

```typescript
// Use the same config object from Option 2
const config = new SmileConfig(
  'your_partner_id',
  'your_auth_token', 
  'https://prod-lambda-url.com',
  'https://test-lambda-url.com'
);

// Initialize with configuration and API key
initialize(false, true, config, 'YOUR_API_KEY'); // false for production, true for sandbox
```

{% endtab %}
{% endtabs %}

## Callback URL

To set the callback URL used for jobs (to deliver results to your own server), use the setCallbackUrl method

{% tabs %}
{% tab title="Android" %}

```kotlin
SmileID.setCallbackUrl(URL("https://smileidentity.com"))
```

{% endtab %}

{% tab title="iOS" %}

```swift
SmileID.setCallbackUrl(url: URL(string: "https://smileidentity.com"))
```

{% endtab %}

{% tab title="Flutter" %}

```dart
SmileID.setCallbackUrl(callbackUrl: Uri.parse("https://smileidentity.com"));
```

{% endtab %}

{% tab title="React Native" %}

```typescript
SmileID.setCallbackUrl("https://smileidentity.com");
```

{% endtab %}

{% tab title="React Native Expo" %}

```typescript
setCallbackUrl("https://smileidentity.com");
```

{% endtab %}
{% endtabs %}

## Environments (Sandbox/Production)

To switch between **Sandbox** and **Production** you should initialize using:

{% tabs %}
{% tab title="Android" %}

```kotlin
SmileID.initialize(context = this, useSandbox = true)
```

{% endtab %}

{% tab title="iOS" %}

```swift
SmileID.initialize(useSandbox: true)
```

{% endtab %}

{% tab title="Flutter" %}

```dart
SmileID.initialize(useSandbox: true, enableCrashReporting: false);
```

{% endtab %}

{% tab title="React Native" %}

```typescript
SmileID.initialize(true); //true if running on sandbox false if running production
```

In all three initialization methods, the first parameter, `useSandBox`, of the initialize function determines the environment. Setting it to `true` enables the **sandbox** environment, while `false` enables the **production** environment.
{% endtab %}

{% tab title="React Native Expo" %}

```typescript
initialize(true, false)
```

In all three initialization methods, the first parameter, `useSandBox`, of the initialize function determines the environment. Setting it to `true` enables the **sandbox** environment, while `false` enables the **production** environment.
{% endtab %}
{% endtabs %}

## Usage

{% tabs %}
{% tab title="Android" %}
**Javadoc**

The latest Javadocs can be found [here](https://javadoc.io/doc/com.smileidentity/android-sdk)

All [Products](https://github.com/smileidentity/docs/blob/main/products/README.md) are implemented using [Jetpack Compose](https://developer.android.com/jetpack/compose) and therefore exposed as Composable functions. *This is the encouraged usage pattern.*

If your application employs the traditional View-based approach, then we also expose [`androidx.fragment.app.Fragment`](https://developer.android.com/jetpack/androidx/releases/fragment) based wrappers around the Composables. You should use `getSupportFragmentManager().setFragmentResultListener(...)` to listen for results. Examples are provided for each product.
{% endtab %}

{% tab title="iOS" %}
**SDK SwiftUI Screens**

All product screens in the iOS SDK are implemented in SwiftUI and are therefore exposed as SwiftUI views. If your project is implemented in UIKit, you can still use the SwiftUI views by embedding them in a [UIHostingController](https://developer.apple.com/documentation/swiftui/uihostingcontroller) and presenting or pushing the views using UIKit's ViewController presentation mechanisms.

**Using the SDK in an Objective-C Project**

Objective-C does not support SwiftUI directly, as SwiftUI is tightly integrated with Swift's type system and runtime. To work around this, you need to use a Swift wrapper that embeds SwiftUI views inside a `UIViewController` using `UIHostingController`.

**Steps**

**1. Create a Swift View Controller Wrapper**

To use SwiftUI views in Objective-C, create a Swift class that embeds the SwiftUI view inside a `UIHostingController`.

**Example:**

```swift
import SmileID
import SwiftUI
import UIKit

@objcMembers
class SelfieCaptureViewModel: NSObject, @preconcurrency SmartSelfieResultDelegate {
    func didSucceed(selfieImage: URL, livenessImages: [URL], apiResponse: SmartSelfieResponse?) {
        // control your application with this responses
        print(selfieImage)
        print(livenessImages.map { $0 })
        print(apiResponse?.code ?? "")
    }

    @MainActor func didError(error: any Error) {
        // handle errors
        print(error.localizedDescription)
        UIApplication.shared.windows.first?.rootViewController?.dismiss(animated: true)
    }
}

@objcMembers
class SelfieCaptureViewController: UIViewController {
    let viewModel: SelfieCaptureViewModel = SelfieCaptureViewModel()

    override func viewDidLoad() {
        super.viewDidLoad()

        embedSwiftUIView()
    }

    private func embedSwiftUIView() {
        let smartSelfieView = SmileID.smartSelfieEnrollmentScreen(delegate: viewModel)
        let viewController = UIHostingController(rootView: smartSelfieView)
        let swiftUIView = viewController.view!

        // Standard UIKit View setup
        swiftUIView.translatesAutoresizingMaskIntoConstraints = false
        swiftUIView.backgroundColor = .white

        addChild(viewController)
        view.addSubview(swiftUIView)
        
        // Constrain the view however you want
        NSLayoutConstraint.activate([
            swiftUIView.topAnchor.constraint(equalTo: view.topAnchor),
            swiftUIView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            swiftUIView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
            swiftUIView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
        ])

        viewController.didMove(toParent: self)
    }
}
```

Applying `@objcMembers` to `SelfieCaptureViewController` and `SelfieCaptureViewModel` ensures that all explicitly defined members are exposed to the Objective-C runtime, avoiding the need to manually annotate each method or property with `@objc`.

**2. Expose Swift Classes to Objective-C**

To enable Objective-C to recognise and use Swift classes in a mixed-language project, you need to create a **Bridging Header**. This header file acts as a link between the two languages, allowing Swift symbols to be exposed to Objective-C.

{% hint style="info" %}
If you already have a bridging header file and at least one Swift file working in your project you can skip this step.
{% endhint %}

**Automatic Approach:** If you don't previously have any Swift file in your project, Xcode can automatically setup the bridging header file for you.

Add a new Swift file to any folder in your Objective-C project and you should get the dialog shown in the image below:

<figure><img src="/files/R1jWDA6txbBq8MbeqgCV" alt=""><figcaption><p>Xcode Bridging Header Dialog</p></figcaption></figure>

Click **"Create Bridging Header"** option and you should now have a Bridging Header in your project for Objective-C and Swift interoperability.

**Manual Approach:** You can also follow these steps to create and configure it manually:

1. In Xcode, go to **File** > **New** > **File...**.
2. Choose **Header File** and name it `YourProjectName-Bridging-Header.h`
3. Add the following import statement in the bridging header:

   ```
   #import "YourProjectName-Swift.h"
   ```
4. In **Build Settings**, find **Objective-C Bridging Header** and set its value to the path of your header file (`YourProjectName/YourProjectName-Bridging-Header.h`).

**3. Use the Swift Wrapper in Objective-C**

Once your Swift wrapper is properly set up and exposed to Objective-C, you can treat it like any other `UIViewController`when instantiating and presenting it in your Objective-C codebase. Now you can instantiate and present the SwiftUI view controller in Objective-C:

**Example:**

```objectivec
#import "ViewController.h"
#import "ExampleObjc-Swift.h"

@import SmileID;

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
}

// your other view controller code.

- (void)showSmartSelfieCapture {
    SelfieCaptureViewController *selfieVC = [[SelfieCaptureViewController alloc] init];
    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:selfieVC];
    [navController setModalPresentationStyle:UIModalPresentationFullScreen];
    [self presentViewController:navController animated:YES completion:nil];
}

// ...
```

**Additional Resources**

For more information on importing Swift into Objective-C, refer to the official Apple documentation: [Importing Swift into Objective-C](https://developer.apple.com/documentation/swift/importing-swift-into-objective-c)

We have also put together a sample [Objective-C project](https://github.com/smileidentity/ios/tree/main/Example-Objc) you can look at for inspiration.
{% endtab %}
{% endtabs %}

## Networking

{% tabs %}
{% tab title="Android" %}
The product screens will handle performing all network requests for you. However, it is also possible to make REST API calls directly via `SmileID.api`. Please refer to the [Javadoc](https://javadoc.io/doc/com.smileidentity/android-sdk) for further details.

You can configure the connect, read, write, and call timeouts for all network requests made by the SDK by building on top of `SmileID.getOkHttpClientBuilder()` and passing the resulting client to `SmileID.initialize(...)` via the `okHttpClient` parameter.

```kotlin
val client = SmileID.getOkHttpClientBuilder()
    .connectTimeout(60, TimeUnit.SECONDS)
    .readTimeout(120, TimeUnit.SECONDS)
    .writeTimeout(120, TimeUnit.SECONDS)
    .callTimeout(180, TimeUnit.SECONDS)
    .build()

SmileID.initialize(context = this, okHttpClient = client)
```

It is advisable not to set these timeouts below the SDK's defaults, to avoid premature timeouts in slow network conditions.
{% endtab %}

{% tab title="iOS" %}
The product screens handle performing network requests for you. However, you can also submit data to the API directly using `SmileID.api`, an instance of `SmileIDService`.

You can configure the request timeout for all network requests made by the SDK by using the `requestTimeout` parameter when initializing the SDK.

```swift
SmileID.initialize(config: config, useSandbox: false, requestTimeout: 120)
```

It is advisable not to set the `requestTimeout` below the value of `SmileID.defaultRequestTimeout`, to avoid premature timeouts in slow network conditions.
{% endtab %}

{% tab title="Flutter" %}
You can make network requests to the Smile ID backend using the `SmileIDService` class, accessible by calling `SmileID.api`
{% endtab %}

{% tab title="React Native" %}
The product views handle performing network requests for you. However, you can also submit data to the Smile ID backend directly using the methods exposed on the `SmileID` module — for example `SmileID.authenticate`, `SmileID.prepUpload`, `SmileID.upload`, `SmileID.doEnhancedKyc`, and the `getSmartSelfieJobStatus` / `pollSmartSelfieJobStatus` family.
{% endtab %}
{% endtabs %}

## Checking Job Status

Use `SmileID.api.pollSmartSelfieJobStatus`, `SmileID.api.pollDocVJobStatus`, or `SmileID.api.pollBiometricKycJobStatus` to poll a given Job's status until it is complete.

{% hint style="info" %}
It is implemented asynchronously, which will emit a response for every poll attempt made.

You must handle and catch errors within your own implementation.
{% endhint %}

The delay and number of attempts is configurable.

Alternatively, you may use `SmileID.api.getSmartSelfieJobStatus`, `SmileID.api.getDocVJobStatus`, or `SmileID.api.getBiometricKycJobStatus` to perform a one-off job status check.

## Crash Reporting

Crash reporting is enabled by default. **Only** crashes *caused by Smile Identity* will be reported. This will not interfere with any other crash reporting you may be doing.

{% tabs %}
{% tab title="Android" %}
It can optionally be disabled by calling `SmileIDCrashReporting.disable()` at runtime or by passing `enableCrashReporting = false` at initialization (*Not Recommended*).
{% endtab %}

{% tab title="iOS" %}
It can optionally be disabled by passing `enableCrashReporting: false` to `SmileID.initialize(...)` (*Not Recommended*).

```swift
SmileID.initialize(config: config, useSandbox: false, enableCrashReporting: false)
```

{% endtab %}
{% endtabs %}

## Submitting to the App Store (iOS Only)

The Smile ID SDK for iOS uses the TrueDepth API. As a result, you must declare this API usage to Apple when submitting your iOS app for review to the App Store. Here is the relevant information you may be asked to provide:

> What information is your app collecting

We use ARKit to capture face 3D spatial orientation and facial expressions.

> For what purposes are you collecting this information

We use this data to ensure the selfie being taken is of a live user for authentication and fraud reduction purposes.

> Will the data be shared with any third parties

The ARKit information is processed entirely locally and the spatial orientation/facial expression data is not submitted to any third (or first) parties

## Resources

All resource identifiers defined by the SDK are prefixed by `si_` so as to prevent naming clashes with your application resources. You may override any resource value -- for further information, see [Customization](/integration-options/mobile/theming.md)

## File Handling (Android only)

Captured files are saved to the result of calling `context.getDir("SmileID", MODE_PRIVATE)`, which is usually: `/data/user/0/<package name>/app_SmileID`

## Troubleshooting

### Camera / webView related issues

Please see the [troubleshooting guide here](/further-reading/troubleshooting/image-capture-issues-on-web-client.md#problem-camera-loading-in-full-screen-in-webview) for situations where the camera is loading in full screen.

### Camera lag or fails with "Camera is closed" during selfie capture

If your application requires other packages or modules that control the camera, you may experience a lagging or unstable video feed during capture. In other cases you will get an error with `"Camera is closed"`.

To resolve this, you need to ensure that Android uses a consistent version of the CameraX library. Please add the following block to your `android/build.gradle.kts` file within the `allprojects {}` section to force all packages to use the same version:

```kts
configurations.configureEach {
        resolutionStrategy {
            force(
                "androidx.camera:camera-lifecycle:1.5.0",
                "androidx.camera:camera-camera2:1.5.0",
                "androidx.camera:camera-video:1.5.0",
                "androidx.camera:camera-core:1.5.0",
                "androidx.camera:camera-view:1.5.0")
        }
    }
```

[^1]: Obtainable at <https://portal.usesmileid.com/sdk>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://legacy-docs.usesmileid.com/integration-options/mobile/getting-started.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
