# WebViews

<Callout icon="⚠️" theme="warn">
  **WebView support is newly formalized.** The requirements and configurations documented here reflect the first official release of WebView as a supported integration method. Support currently covers v2 integrations only and a defined set of core modules. Contact your Incode representative if you have questions about your specific configuration.
</Callout>

A WebView is an embedded browser component within a native mobile application. Rather than building a native SDK integration, you can load Incode’s hosted verification flow (a Workflow or Flow URL) inside a WebView component in their iOS or Android app.

Incode officially supports this integration method for the configurations and modules described on this page.

## How it works

WebView integration follows the same model as a standard [Flows / Workflows](https://developer.incode.com/update/docs/web-integrations-flows-workflows) integration:

1. Your backend starts an onboarding session and generates a Workflow URL.
2. Your native app loads that URL in a WebView component.
3. The user completes identity verification inside the embedded browser.
4. You retrieve results via Dashboard or webhook.

The key difference from a standard web integration is that your native app must be configured to grant the WebView access to the device hardware and browser APIs that Incode requires.

## Supported platforms and frameworks

| Platform | Supported component        | System browser variant   |
| -------- | -------------------------- | :----------------------- |
| Android  | `WebView` (Android native) | Chrome Custom Tabs       |
| iOS      | `WKWebView`                | `SFSafariViewController` |

<Callout icon="📘" theme="info">
  **Note**: Support covers **v2 integrations only**. Legacy v1 integrations are not covered under this support model.
</Callout>

## Supported modules

The following modules are validated for WebView use:

* ID Capture (ID scan)
* Face Capture (selfie)
* Proof of Address / Document Capture
* Deepsight
* Face Authentication
* CURP

Other modules may function in WebView environments but are not covered under validated support at this time.

## System requirements

Your native app must meet the following requirements for a WebView integration with Incode to function correctly.

### Required permissions

Your native app must request and pass through the following permissions to the WebView:

* **Camera**: Required for ID scan and selfie capture
* **Microphone**: Required for video selfie and video conference modules
* **Screen recording**: Required for Deepsight
* **Geolocation**: Required if the Geolocation module is included in your flow

Permissions denied at the native app level cannot be recovered inside the WebView. If a user has previously denied a permission, your app must direct them to re-enable it in device settings before launching the WebView.

### Required browser APIs

The following web platform APIs must remain enabled in your WebView configuration:

* `getUserMedia` (camera and microphone access)
* `MediaRecorder`
* JavaScript execution (must not be disabled)
* Local storage / session storage

### Minimum memory

The WebView must have access to sufficient device memory to load Incode's SDK assets and run capture modules. Memory-constrained configurations may cause loading failures, particularly for modules that involve real-time processing (Deepsight, video selfie).

* **RAM:** ≥ 2 GB
* **Free storage:** ≥ 200 MB (iOS); ≥ 200–300 MB (Android)

### Operating system minimums

| Platform | Minimum      | Recommended    |
| :------- | :----------- | :------------- |
| Android  | 7.0 (API 24) | 8.0+ (API 26+) |
| iOS      | 14.5         | 15.0+          |

## Known limitations

* Custom WebView configurations that disable standard browser APIs are not supported.
* Non-standard or deprecated WebView implementations (for example, `UIWebView` on iOS) are not supported.
* Third-party in-app browsers (for example, Instagram or TikTok) may have additional constraints and broken UI behavior and are not officially supported configurations.
* WebViews embedded inside game or framework engines (for example, Unity) are not covered by standard WebView support.
* Video Selfie and Video Conference module support in WebView is not yet validated and is excluded from current coverage. Full validation is expected in H2 2026.
* iOS Simulator cannot be used for full module testing (camera, liveness, motion). Use a physical device for Deepsight, liveness, and media module testing.

## Integration guide

### Android (Native WebView)

Configure your `WebView` instance to enable the required permissions and APIs before loading the Incode session URL:

```kotlin
webView.settings.apply {
    javaScriptEnabled = true
    domStorageEnabled = true
    mediaPlaybackRequiresUserGesture = false
    allowFileAccess = true
    allowContentAccess = true
    setGeolocationEnabled(true)
    javaScriptCanOpenWindowsAutomatically = true
    mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
}

webView.webChromeClient = object : WebChromeClient() {
    override fun onPermissionRequest(request: PermissionRequest) {
        request.grant(request.resources) // Grant camera, microphone, etc.
    }

    override fun onShowFileChooser(
        webView: WebView,
        filePathCallback: ValueCallback<Array<Uri>>,
        fileChooserParams: FileChooserParams
    ): Boolean {
        // Handle <input type="file"> for document capture
        return true
    }
}

webView.loadUrl(onboardingUrl)
```

Required manifest permissions:

* `INTERNET`
* `CAMERA`
* `RECORD_AUDIO`
* `STORAGE` (only if file uploads or downloads to device storage are needed)

> **Chrome Custom Tabs:** Runs inside the system Chrome process. Host app has limited control; permissions are system-managed.

### iOS (WKWebView)

Configure your `WKWebView` with the appropriate `WKWebViewConfiguration` to allow media capture:

```swift
let config = WKWebViewConfiguration()
config.allowsInlineMediaPlayback = true
config.mediaTypesRequiringUserActionForPlayback = []
config.allowsPictureInPictureMediaPlayback = false

let webView = WKWebView(frame: .zero, configuration: config)
```

On iOS 15 and later, implement the following `WKUIDelegate` methods to enable camera/microphone access and Deepsight/liveness support:

* `decideMediaCapturePermissionsFor` — enables `getUserMedia` for camera and microphone
* `requestDeviceOrientationAndMotionPermissionFor` — required for Deepsight and liveness modules

Your `Info.plist` must include usage descriptions for all permissions your WebView will request. Failure to include these will cause the OS to deny the permission silently. Required keys:

* `NSCameraUsageDescription`
* `NSMicrophoneUsageDescription`
* `NSLocationWhenInUseUsageDescription`
* `NSMotionUsageDescription`

> **SFSafariViewController:** No app-level delegates are required. System Safari handles all permissions using the plist keys above.

## Debugging

WebView sessions can be difficult to debug because native browser developer tools are not accessible by default.

* **Android**: Enable WebView debugging and connect via Chrome DevTools (`chrome://inspect`).
* **iOS**: Enable Web Inspector for your WKWebView and connect via Safari’s Develop menu.

Both test applications (Android `webview.apk` and iOS `IncodeVerifyExample`) support console log forwarding. Contact your Incode representative for access to these test applications.

## Contact

If you are evaluating or implementing a WebView integration, contact your Incode representative to discuss your configuration and ensure it falls within supported parameters.
