Didit Console

iOS & Android

If you want to integrate the verification process directly into your mobile application, you should first create a session and then open the generated URL within your app. This guide will walk you through the process for React Native, iOS, and Android.

Creating a Session

To create a session, follow the instructions in the Creating a Verification Session documentation. This will provide you with a session URL that you can open in your mobile app.

Opening the Session URL

Once you have created a session and obtained the URL, you can open it in your mobile app using a WebView. Here's how to do it for React Native, iOS, and Android:

import React from 'react';
import { WebView } from 'react-native-webview';

const VerificationScreen = () => {
  return (
    <WebView
      source={{ uri: '{session_url}' }}
  		// Make sure to set the user agent to a generic mobile one
    	userAgent="Mozilla/5.0 (Linux; Android 10; Mobile) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36"
      // Mandatory props
      mediaPlaybackRequiresUserAction={false}
      allowsInlineMediaPlayback={true}
      // Android-specific props
      domStorageEnabled={true}
      // Optional props for performance
      androidHardwareAccelerationDisabled={false}
      androidLayerType="hardware"
  	/>
  );
};

export default VerificationScreen;
import UIKit
import WebKit

class VerificationViewController: UIViewController, WKNavigationDelegate {
  private var webView: WKWebView!

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

  private func setupWebView() {
    // Create WKWebView configuration
    let configuration = WKWebViewConfiguration()
    configuration.allowsInlineMediaPlayback = true
    configuration.mediaTypesRequiringUserActionForPlayback = []

    // Create WKWebView with configuration
    webView = WKWebView(frame: view.bounds, configuration: configuration)
    webView.navigationDelegate = self
    webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

    // Add webView to view hierarchy
    view.addSubview(webView)

    // Configure content settings
    webView.configuration.preferences.javaScriptEnabled = true

    // Make sure to set the user agent to a generic mobile one
    webView.customUserAgent = "Mozilla/5.0 (Linux; Android 10; Mobile) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36"


    // Load URL
    if let url = URL(string: "{session_url}") {
      let request = URLRequest(url: url)
      webView.load(request)
    }

    // Handle permissions
    webView.configuration.mediaTypesRequiringUserActionForPlayback = [] // Allow autoplay
  }

  // MARK: - WKNavigationDelegate

  func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
    // Handle navigation permissions
    decisionHandler(.allow)
  }

  func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {
    // Handle response permissions
    decisionHandler(.allow)
  }
}
#import <UIKit/UIKit.h>
#import <WebKit/WebKit.h>

@interface VerificationViewController : UIViewController <WKNavigationDelegate>

@end

// VerificationViewController.m
#import "VerificationViewController.h"

@interface VerificationViewController ()
@property(nonatomic, strong) WKWebView *webView;
@end

@implementation VerificationViewController

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

- (void)setupWebView {
  // Create WKWebView configuration
  WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
  configuration.allowsInlineMediaPlayback = YES;
  configuration.mediaTypesRequiringUserActionForPlayback =
      WKAudiovisualMediaTypeNone;

  // Create WKWebView with configuration
  self.webView = [[WKWebView alloc] initWithFrame:self.view.bounds
                                    configuration:configuration];
  self.webView.navigationDelegate = self;
  self.webView.autoresizingMask =
      UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

  // Add webView to view hierarchy
  [self.view addSubview:self.webView];

  // Configure content settings
  self.webView.configuration.preferences.javaScriptEnabled = YES;

  // Make sure to set the user agent to a generic mobile one
  [self.webView
      setCustomUserAgent:
          @"Mozilla/5.0 (Linux; Android 10; Mobile) AppleWebKit/537.36 (KHTML, "
          @"like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36"];

  // Load URL
  NSURL *url = [NSURL URLWithString:@"{session_url}"];
  if (url) {
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [self.webView loadRequest:request];
  }
}

#pragma mark - WKNavigationDelegate

- (void)webView:(WKWebView *)webView
    decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction
                    decisionHandler:
                        (void (^)(WKNavigationActionPolicy))decisionHandler {
  // Handle navigation permissions
  decisionHandler(WKNavigationActionPolicyAllow);
}

- (void)webView:(WKWebView *)webView
    decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse
                      decisionHandler:(void (^)(WKNavigationResponsePolicy))
                                          decisionHandler {
  // Handle response permissions
  decisionHandler(WKNavigationResponsePolicyAllow);
}

@end
import android.os.Bundle;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import androidx.appcompat.app.AppCompatActivity;

public class VerificationActivity extends AppCompatActivity {
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_verification);

    WebView webView = findViewById(R.id.webview);

    // Enable JavaScript
    WebSettings webSettings = webView.getSettings();
    webSettings.setJavaScriptEnabled(true);

    // Enable inline media playback (i.e., prevents fullscreen mode on video play)
    webSettings.setMediaPlaybackRequiresUserGesture(false);

    // Set WebChromeClient to handle media playback
    webView.setWebChromeClient(new WebChromeClient());

    // Make sure to set the user agent to a generic mobile one
    webView.setUserAgentString("Mozilla/5.0 (Linux; Android 10; Mobile) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36");

    // Load the session URL
    webView.loadUrl("{session_url}");
  }
}
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:webview_flutter_wkwebview/webview_flutter_wkwebview.dart';
import 'package:webview_flutter_android/webview_flutter_android.dart';

class VerificationScreen extends StatefulWidget {
  const VerificationScreen({super.key});

  @override
  State<VerificationScreen> createState() => _VerificationScreenState();
}

class _VerificationScreenState extends State<VerificationScreen> {
  late final WebViewController _controller;

  @override
  void initState() {
    super.initState();
    _setupWebView();
  }

void _setupWebView() {
  // Configure platform-specific parameters
  final params = WebViewPlatform.instance is WebKitWebViewPlatform
    ? WebKitWebViewControllerCreationParams(
    allowsInlineMediaPlayback: true,
    mediaTypesRequiringUserAction: const {},
    )
    : const PlatformWebViewControllerCreationParams();

  // Initialize the WebView controller and make sure to set the user agent to a generic mobile one
  _controller = WebViewController.fromPlatformCreationParams(params)
    ..setJavaScriptMode(JavaScriptMode.unrestricted)
    ..setUserAgent(
    'Mozilla/5.0 (Linux; Android 10; Mobile) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36')
    ..loadRequest(Uri.parse('{session_url}'));

  // Configure platform-specific settings
  final platformController = _controller.platform;

  // Handle permissions
  platformController.setOnPlatformPermissionRequest((request) {
                                                    request.grant();
});

// Android-specific configuration
if (platformController is AndroidWebViewController) {
  platformController.setGeolocationPermissionsPromptCallbacks(
    onShowPrompt: (params) async {
    return const GeolocationPermissionsResponse(
      allow: true,
      retain: true
    );
  },
    onHidePrompt: () {},
      );
  platformController.setMediaPlaybackRequiresUserGesture(false);
}
}

  @override
Widget build(BuildContext context) {
  return WebViewWidget(controller: _controller);
}
}

These settings will ensure that:

  1. Inline media playback is enabled
  2. Media playback doesn't require user action
  3. DOM storage is enabled for Android
  4. Hardware acceleration is optimized for Android

Handling the Callback

After the verification process is complete, the system will redirect to the callback URL you specified when creating the session. You should implement a way to handle this callback in your mobile app.

One common approach is to use a custom URL scheme for your app and set it as the callback URL. This allows your app to intercept the callback and handle it appropriately.

For more information on creating a session and specifying a callback URL, refer to the Creating a Verification Session documentation.

By following these steps, you can integrate the Didit verification process directly into your React Native, iOS, or Android application, providing a seamless experience for your users.

Example Implementation

For complete examples of implementing Didit verification in mobile applications, check out our demo repositories: