Skip to main content
This guide explains how to integrate LiveForm as a WebView in a customer mobile app. Audience: Mobile engineers integrating LiveForm into an existing iOS or Android app.

Implementation Goals

The customer app must implement the following flow:
  1. Build the LiveForm URL using the pid received from the customer server or app.
  2. Check app permissions required by LiveForm before opening the WebView.
  3. Open the LiveForm URL in a full-screen WebView.
  4. Configure the WebView to support camera capture, image upload, cookies, and external link navigation.

Supported Versions and Minimum Requirements

LiveForm is an HTTPS-based web application. The app’s WebView must fully support modern browser features, camera permissions, file selection, and cookie/storage.
PlatformMinimumRecommendedNotes
iOSiOS 15+iOS 16+iOS 15+ supports the WKUIDelegate media capture permission callback to restrict grants to the LiveForm host.
AndroidAndroid 9, API 28+Android 10, API 29+Use the latest Android System WebView or Chrome for stable file selection and camera capture.
Android WebViewUpdatable Android System WebView or ChromeLatest Android System WebView or ChromeFile selection, camera capture, and cookie/storage behavior can be affected by WebView/Chrome version.
React Nativereact-native-webview 13.x+Latest stableNative apps can implement the same functionality directly using WKWebView/Android WebView.
Device testing scope:
  • Verify the full flow on Android 9 (API 28)+: app install, WebView loading, file selection, camera capture, cookie/storage.
  • Verify the full flow on iOS 15+: WKWebView file selection, camera capture, cookie/storage.
  • Final approval requires completing a real LiveForm submission — camera capture, upload, submit, and returnUrl/deep link navigation.

LiveForm URL

The customer app uses only the LiveForm production host. Pass pid as a query parameter.
https://form.argosidentity.com?pid={pid}
Always URL-encode pid before inserting it into the URL.
The app does not need to distinguish between hosts or form type paths — the pid alone identifies the LiveForm session.

App Permissions

LiveForm uses the camera and image upload features inside the WebView. When running LiveForm as a WebView in a mobile app, the customer app must obtain camera and file access permissions before the WebView opens — permissions that would normally be handled by the browser.
Requesting and verifying camera and photo library (or media) permissions at the app level before opening the WebView is required. If required permissions are not granted, LiveForm camera capture or image upload may not work — do not open the WebView in that state.
Add the following usage descriptions to Info.plist:
<key>NSCameraUsageDescription</key>
<string>Camera access is required for LiveForm ID document capture.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Photo library access is required for LiveForm image upload.</string>

Required Integration Flow

User action
  └─ Customer app starts LiveForm
      └─ Build LiveForm URL from pid

Before WebView opens
  ├─ Check camera permission
  ├─ Check photo library/media permission
  └─ Open full-screen WebView

Inside WebView
  ├─ Allow JavaScript and DOM storage
  ├─ Allow cookies
  ├─ Allow inline media and media capture
  ├─ Load http/https/data/about URLs inside WebView
  └─ Forward custom schemes to external apps
Do not open the WebView if the URL is invalid or permission checks have not completed.

WebView Configuration

The WebView must allow JavaScript, storage, cookies, media playback, and media capture.
When using react-native-webview, the underlying WebChromeClient (Android) and WKUIDelegate (iOS) details are handled by the library’s native layer. Set the WebView props below, then verify the Android and iOS checklists separately on real devices.
import { Linking } from 'react-native';
import { WebView } from 'react-native-webview';

function openExternalUrl(url: string) {
  Linking.canOpenURL(url)
    .then((supported) => {
      if (supported) return Linking.openURL(url);
      return undefined;
    })
    .catch(() => undefined);
}

export function LiveFormWebView({ url }: { url: string }) {
  return (
    <WebView
      source={{ uri: url }}
      originWhitelist={['*']}
      javaScriptEnabled
      domStorageEnabled
      sharedCookiesEnabled
      thirdPartyCookiesEnabled
      allowsInlineMediaPlayback
      mediaPlaybackRequiresUserAction={false}
      mediaCapturePermissionGrantType="grantIfSameHostElsePrompt"
      allowsFullscreenVideo
      allowFileAccess
      mixedContentMode="compatibility"
      setSupportMultipleWindows={false}
      onOpenWindow={({ nativeEvent }) => {
        if (nativeEvent.targetUrl) openExternalUrl(nativeEvent.targetUrl);
      }}
      onShouldStartLoadWithRequest={({ url: nextUrl }) => {
        if (
          nextUrl === 'about:blank' ||
          nextUrl.startsWith('about:') ||
          nextUrl.startsWith('data:') ||
          nextUrl.startsWith('http://') ||
          nextUrl.startsWith('https://')
        ) {
          return true;
        }

        openExternalUrl(nextUrl);
        return false;
      }}
    />
  );
}
Key Settings Reference
SettingReason
javaScriptEnabledLiveForm runs as a web application.
domStorageEnabledAllows LiveForm to use browser storage.
sharedCookiesEnabled / thirdPartyCookiesEnabledMaintains cookie behavior similar to a standard browser.
allowsInlineMediaPlaybackAllows media UI to operate inside the WebView where supported.
mediaCapturePermissionGrantTypeEnables media capture permission handling for the LiveForm host.
setSupportMultipleWindows={false}Keeps new window flows within the app-controlled WebView path.
onShouldStartLoadWithRequestForwards unknown custom schemes to external apps so they don’t break the WebView.

LiveForm URL Builder

const LIVE_FORM_ORIGIN = 'https://form.argosidentity.com';

export function buildLiveFormUrl(pid: string) {
  return `${LIVE_FORM_ORIGIN}?pid=${encodeURIComponent(pid.trim())}`;
}

Permission Request Example (Expo/React Native)

import * as ImagePicker from 'expo-image-picker';

export async function requestLiveFormPermissions() {
  const camera = await ImagePicker.requestCameraPermissionsAsync();
  const mediaLibrary = await ImagePicker.requestMediaLibraryPermissionsAsync();

  return {
    granted: camera.granted && mediaLibrary.granted,
    camera,
    mediaLibrary,
  };
}
If permission is denied:
  • Do not open the WebView.
  • Show a message explaining that camera and photo library permissions are required for LiveForm capture and upload.
  • Provide a button to navigate to the app settings screen.

Full-Screen Layout

LiveForm works best when it occupies as much of the screen as possible. Recommendations:
  • Hide the native header on the WebView route.
  • Apply safe area insets to avoid the notch and home indicator.
  • If the header is hidden, provide a small app-level back button.
  • Do not embed the WebView inside a card or modal — let it fill the screen directly.
┌──────────────────────────┐
│  back                    │
│ ┌──────────────────────┐ │
│ │                      │ │
│ │      LiveForm        │ │
│ │      WebView         │ │
│ │                      │ │
│ └──────────────────────┘ │
└──────────────────────────┘

Verification Checklist

Verify on both iOS and Android.
Verification approachThe customer app should implement its own WebView screen based on the sample code provided, then verify the real LiveForm URL and a permissions/feature test page separately.
  • LiveForm URL mode: Verify the actual submission flow on the LiveForm production host.
  • Permissions/feature test page: Verify WebView storage/cookie, fetch, file input, and camera capture input in a single sequential flow, independent of LiveForm state.
Passing the permissions/feature test confirms the WebView mechanism is working, but does not guarantee a successful LiveForm submission. Final approval requires passing both modes.
URL and Navigation
  • A LiveForm URL in the format https://form.argosidentity.com?pid={pid} opens successfully.
  • pid is URL-encoded before being passed.
  • External custom schemes open in an external app or fail gracefully.
Permissions
  • Camera permission is verified before entering the WebView on first launch.
  • Photo library/media permission is verified before entering the WebView on first launch.
  • A recoverable message is shown if permission is denied.
  • The “Open Settings” button navigates to the app settings screen.
WebView Behavior
  • LiveForm loads with JavaScript enabled.
  • The camera UI opens when capturing an ID document.
  • The picker opens for image upload.
  • Cookies and storage persist during normal WebView navigation.
  • A loading state is shown while the page loads.
  • A recoverable error message is shown on WebView load error or HTTP error.

Troubleshooting

Check:
  • Was the app-level camera permission requested and granted before opening the WebView?
  • Is NSCameraUsageDescription set on iOS?
  • Is android.permission.CAMERA set on Android?
  • Are media capture settings enabled in the WebView?
If camera blocking persists in an in-app browser (WebView) environment, see Android & WebView Camera Troubleshooting.
Check:
  • Was photo library or media permission requested and granted?
  • Is NSPhotoLibraryUsageDescription set on iOS?
  • Are Android media permissions configured correctly for the target SDK and picker implementation?
Check:
  • Does the URL include a valid pid?
  • Is the device connected to a network?
  • Are JavaScript and DOM storage enabled?
  • Did the WebView callback receive an HTTP or network error?