Skip to main content

Embedding in WebView

Example https://github.com/Jumio/mobile-webview

The Web Client can be embedded in a WebView in your native mobile application.

UI/UX Considerations​

  • Start verification only after the user initiates action.
  • Show branded loading screens during token generation.
  • Inform users about steps before starting verification.
  • Provide retry and fallback paths.

Android WebView​

You can embed the Web Client in a native Android WebView.

Permissions and Settings​

Permission in the AndroidManifest​

Make sure that all required permissions are granted by adding them to the AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
General​
  • android.permission.INTERNET - Remote resources access.
  • android.permission.CAMERA - Camera capture.

The permissions for the upload functionality depend on the target API level - see the official Android Developer Documentation for further information.

Upto API Level 32​
  • android.permission.READ_EXTERNAL_STORAGE
From API Level 33 Onwards​
  • android.permission.READ_MEDIA_AUDIO
  • android.permission.READ_MEDIA_VIDEO
  • android.permission.READ_MEDIA_IMAGES
  • android.permission.MODIFY_AUDIO_SETTINGS
  • android.permission.RECORD_AUDIO

Request Permissions at Runtime​

In addition to defining the permissions in the Manifest, you also need to request them during runtime before the webview is started. A full implementation can be found in the sample apps MainActivity.kt.

Prerequisites​

In our sample, we use ActivityCompats OnRequestPermissionResultCallback. More information about requesting runtime permissions can be found in the official Android Developer Documentation.

Permissions to Be Requested​
val permissions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
arrayOf(
Manifest.permission.CAMERA,
Manifest.permission.READ_MEDIA_AUDIO,
Manifest.permission.READ_MEDIA_IMAGES,
Manifest.permission.READ_MEDIA_VIDEO,
Manifest.permission.MODIFY_AUDIO_SETTINGS,
Manifest.permission.RECORD_AUDIO,
)
} else {
arrayOf(
Manifest.permission.CAMERA,
Manifest.permission.READ_EXTERNAL_STORAGE,
)
}
Identify Permissions Not Granted​
val missingPermissions = permissions.filter { permission ->
ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED
}.toTypedArray()
Request All Missing Permissions​
if (missingPermissions.isNotEmpty()) {
ActivityCompat.requestPermissions(this, missingPermissions, PERMISSION_REQUEST_CODE)
} else {
showWebView(url)
}
Implement OnRequestPermissionResultCallback​

Check for the request code that you set while requesting the permissions, and see if all permissions are granted. If not, handle the denied permissions accordingly.

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)

if (requestCode == PERMISSION_REQUEST_CODE) {
val deniedPermissions = permissions.filterIndexed { index, _ ->
grantResults[index] != PackageManager.PERMISSION_GRANTED
}

if (deniedPermissions.isNotEmpty()) {
handleDeniedPermissions(deniedPermissions)
} else {
showWebView(requestedUrl)
}
}
}

Configure the WebView​

Apply settings​

The following settings are required for the native WebView for Android. A full implementation can be found in the sample apps WebViewFragment.kt.

binding.webview.apply {
settings.apply {
allowFileAccess = true
allowContentAccess = true
domStorageEnabled = true
javaScriptEnabled = true
@Suppress("DEPRECATION")
allowUniversalAccessFromFileURLs = true
javaScriptCanOpenWindowsAutomatically = true
mediaPlaybackRequiresUserGesture = false
}
}
  • Enable javaScriptEnabled – Allows the WebView to execute JavaScript.
  • Allow allowFileAccess – Enables file access within WebView.
  • Allow allowFileAccessFromFileUrls – Determines whether JavaScript running in the context of a file:// URL can access content from other file:// URLs.
  • Allow allowUniversalAccessFromFileUrls – Determines whether JavaScript running in the context of a file:// URL can access content from any origin.
  • Allow allowContentAccess – Enables content URL access within WebView.
  • Allow javaScriptCanOpenWindowsAutomatically – Lets JavaScript open windows automatically.
  • Enable domStorageEnabled – Enables the DOM storage API.
  • Do not allow mediaPlaybackRequiresUserGesture – Specifies whether the WebView requires a user gesture to play media.
Handle permission request​

Grant the webviews android.webkit.resource.VIDEO_CAPTURE permission request once it is received. Check if the Camera permission is granted - if not, handle accordingly.


binding.webview.webChromeClient = object : WebChromeClientFullScreen() {
// Grant permissions for camera
override fun onPermissionRequest(request: PermissionRequest) {
val activity = activity ?: return
activity.runOnUiThread {
if (request.resources.contains("android.webkit.resource.VIDEO_CAPTURE")) {
if (ContextCompat.checkSelfPermission(
requireActivity(),
Manifest.permission.CAMERA
) == PackageManager.PERMISSION_GRANTED
) {
request.grant(request.resources)
} else {
// Handle not granted permission
}
}
}
}
}

Embedding the Required Script​

PostMessage communication You can handle messages from the Web Client using the same method as described in Optional iFrame Logging.

You will need to register a postMessage handler and put the relevant code sections in the PostMessageHandler class as in the example below.

kotlin
binding.webview.addJavascriptInterface(PostMessageHandler(), "__NVW_WEBVIEW_HANDLER__")

    class PostMessageHandler {
@JavascriptInterface
fun postMessage(json: String?, transferList: String?): Boolean {
/*
There we're handling messages from the client, it's the same as for iFrame logging;
*/
Log.d(TAG, "postMessage triggered, json: " + json.toString())
return true
}
}

Use of iProov​

Be aware that if iProov is included in your workflow it is necessary to extend the WebChromeClient class to implement a custom view, in order to handle certain iProov full screen requirements.

See WebviewFragment.kt, specifically WebChromeClientFullScreen inner class.

Sample App​

Check out our Sample App for the Native Android WebView.

Sample code​

iOS WebView​

Jumio supports two types of WebView for iOS,

  • Safari WebView
  • Native iOS WebView

Permissions and Settings​

Camera Permissions​

To enable camera access within the WebView (e.g., for capturing a photo of a user's ID, Liveness or Document), your iOS app must request the camera permission from the user. Please ensure that you add the following entry to your app's Info.plist file:

<key>NSCameraUsageDescription</key>
<string>This will allow ${PRODUCT_NAME} to take photos of your credentials.</string>

Location Permissions​

To enable location-based functionality within the WebView (e.g., for determining the user's region and showing the correct list of supported IDs), your iOS app must request the appropriate permission from the user. Please add the following entries to your app’s Info.plist file:

<key>NSLocationWhenInUseUsageDescription</key>
<string>This will allow ${PRODUCT_NAME} to use your current location when app is in foreground.</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>This will allow ${PRODUCT_NAME} to use your current location when app is in background.</string>
note

Jumio only uses location when app is in foreground hence we recommend including NSLocationWhenInUseUsageDescription key for requesting location access. If your app requires location access even when the app is in background, you should also include NSLocationAlwaysUsageDescription.

Safari WebView​

This section describes how to embed Web Client in a Safari View Controller (SFSafariViewController).

Sample App​

Check out our Sample App for the iOS Safari WebView.

Sample Code​

Native iOS WebView​

This section describes how to embed the Web Client in a native iOS WebView (WKWebView).

Embedding the Required Script​

PostMessage communication. You can handle messages from the Web Client using the same method as described in Optional iFrame Logging.

You will need to register a userContentController:

       webView.configuration.userContentController.add(self, name: "__NVW_WEBVIEW_HANDLER__")
extension ViewController: WKScriptMessageHandler {
func userContentController(_ userController: WKUserContentController, didReceive message: WKScriptMessage) {
if message.name == "__NVW_WEBVIEW_HANDLER__", let messageBody = message.body as? String {
// do something here with message
// print is only an example
print(messageBody)
}
}
}

Sample App​

Check out our Sample App for the Native iOS WebView.

info

Please also enable inline Playback for the WebView in the Storyboard/UI builder.

Sample Code​

ViewController.swift Example