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 afile://URL can access content from otherfile://URLs. - Allow
allowUniversalAccessFromFileUrls– Determines whether JavaScript running in the context of afile://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
-
AndroidManifest.xml example
-
build.gradle example
-
WebviewFragment.kt example
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>
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
- ViewController.swift example
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.
Please also enable inline Playback for the WebView in the Storyboard/UI builder.
Sample Code
ViewController.swift Example