diff --git a/README.md b/README.md
index 040485b..91eb00b 100755
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
Official Jumio Mobile SDK plugin for Apache Cordova
-This plugin is compatible with version 4.11.0 of the Jumio SDK.
+This plugin is compatible with version 4.12.0 of the Jumio iOS SDK and version 4.12.1 of the Jumio Android SDK.
If you have questions, please reach out to your Account Manager or contact [Jumio Support](#support).
# Table of Contents
@@ -16,6 +16,8 @@ If you have questions, please reach out to your Account Manager or contact [Jumi
- [Customization](#customization)
- [Configuration](#configuration)
- [Callbacks](#callbacks)
+- [Result Objects](#result-objects)
+- [Local Models for ID Verification and Liveness](#local-models-for-id-verification-and-liveness)
- [FAQ](#faq)
- [Android Issues](#android-issues)
- [iOS Issues](#ios-issues)
@@ -37,7 +39,7 @@ cordova create MyProject com.my.project "MyProject"
cd MyProject
cordova platform add ios
cordova platform add android
-cordova plugin add https://github.com/Jumio/mobile-cordova.git#v4.11.0
+cordova plugin add https://github.com/Jumio/mobile-cordova.git#v4.12.0
cd platforms/ios && pod install
```
@@ -67,6 +69,16 @@ To use the native Jumio Android component, your App needs to support AndroidX. T
```
+__Upgrade Gradle build tools__
+The plugin requires at least version 8.0.0 of the Android build tools. This transitively requires an upgrade of the Gradle wrapper to version 8 and an update to Java 11.
+
+If necessary, modify the Gradle Wrapper version in `android/gradle.wrapper/gradle-wrapper.properties`:
+
+```groovy
+...
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
+```
+
#### Proguard
For information on Android Proguard Rules concerning the Jumio SDK, please refer to our [Android Guides](https://github.com/Jumio/mobile-sdk-android#proguard).
@@ -236,19 +248,25 @@ JumioSDK will return a JSONObject `documentData` with all extracted data in cas
| compositeValid | BOOL | | True if composite check digit is valid, otherwise false |
-## Local Models for JumioDocfinder
+## Local Models for ID Verification and Liveness
-If you are using our JumioDocFinder module, you can download our encrypted models and add them to your bundle from [here](https://cdn.mobile.jumio.ai/model/classifier_on_device_ep_99_float16_quant.enc) and [here](https://cdn.mobile.jumio.ai/model/normalized_ensemble_passports_v2_float16_quant.enc).
+Our SDK requires several machine learning models to work best. We recommend to download the files and add them to your project without changing their names (the same way you add Localization files). This will save two network requests on runtime to download these files.
-We recommend to download the files and add them to your project without changing their names (the same way you add Localization files). This will save two network requests on runtime to download these files.
+### Preloading models
+
+You can preload the ML models before initializing the Jumio SDK. To do so set the completion block with `JumioMobileSDK.setPreloaderFinishedBlock` and start the preloading with `JumioMobileSDK.preloadIfNeeded`.
### iOS
-You also need to copy those files to the `ios/Assets` folder for Cordova to recognize them.
+You can find the models in the [Bundling models in the app](https://github.com/Jumio/mobile-sdk-ios/blob/master/docs/integration_guide.md#bundling-models-in-the-app) section of our integration guide.
+
+You also need to copy those files to the "ios/Assets" folder for Cordova to recognize them.
### Android
-You need to copy those files to the assets folder of your Android project (Path: `app/src/main/assets/`)
+You can find the models in the [Bundling models in the app](https://github.com/Jumio/mobile-sdk-android/blob/master/docs/integration_guide.md#bundling-models-in-the-app) section of our integration guide.
+
+You need to copy those files to the assets folder of your Android project (Path: "app/src/main/assets/").
# FAQ
diff --git a/demo/README.md b/demo/README.md
index 71710ec..ed65234 100755
--- a/demo/README.md
+++ b/demo/README.md
@@ -4,7 +4,7 @@ Demonstrates how to use the JumioMobileSDK plugin.
## Prerequisites
* Cordova CLI 12.0.0
-* NodeJS 22.6.0
+* NodeJS 23.6.0
## Hooks
diff --git a/demo/config.xml b/demo/config.xml
index a1ddc33..873e3eb 100755
--- a/demo/config.xml
+++ b/demo/config.xml
@@ -1,5 +1,5 @@
-
+
DemoApp
A sample Apache Cordova application that responds to the deviceready event.
@@ -17,6 +17,7 @@
+
@@ -78,8 +79,8 @@
-
-
+
+
diff --git a/demo/gradle/wrapper/gradle-wrapper.properties b/demo/gradle/wrapper/gradle-wrapper.properties
index a96d09c..acf918e 100755
--- a/demo/gradle/wrapper/gradle-wrapper.properties
+++ b/demo/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip
\ No newline at end of file
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
\ No newline at end of file
diff --git a/demo/package.json b/demo/package.json
index 7aa6243..0ae803e 100755
--- a/demo/package.json
+++ b/demo/package.json
@@ -1,7 +1,7 @@
{
"name": "com.jumio.cordova.demo",
"displayName": "DemoApp",
- "version": "4.11.0",
+ "version": "4.12.0",
"description": "A sample Apache Cordova application that responds to the deviceready event.",
"main": "index.js",
"scripts": {
diff --git a/demo/scripts/addPackagingOptions.js b/demo/scripts/addPackagingOptions.js
new file mode 100755
index 0000000..d5944c4
--- /dev/null
+++ b/demo/scripts/addPackagingOptions.js
@@ -0,0 +1,55 @@
+const fs = require('fs');
+const path = require('path');
+
+module.exports = function (context) {
+ const buildGradlePath = path.join('platforms', 'android', 'app', 'build.gradle');
+
+ if (fs.existsSync(buildGradlePath)) {
+ let buildGradleContents = fs.readFileSync(buildGradlePath, 'utf8');
+
+ if (!buildGradleContents.includes('packagingOptions')) {
+ buildGradleContents = insertPackagingOptions(buildGradleContents);
+ fs.writeFileSync(buildGradlePath, buildGradleContents, 'utf8');
+ console.log('Successfully added packagingOptions to build.gradle.');
+ } else {
+ console.log('packagingOptions already present in build.gradle.');
+ }
+ } else {
+ console.log('build.gradle file not found.');
+ }
+};
+
+function insertPackagingOptions(buildGradleContents) {
+ const packagingOptionsBlock = `
+ packagingOptions {
+ resources.excludes.add("META-INF/versions/9/OSGI-INF/MANIFEST.MF")
+ resources.excludes.add("META-INF/kotlin-project-structure-metadata.json")
+ resources.excludes.add("META-INF/kotlinx_coroutines_core.version")
+ resources.excludes.add("META-INF/LICENSE.md")
+ resources.excludes.add("META-INF/LICENSE-notice.md")
+ resources.excludes.add("commonMain/default/manifest")
+ resources.excludes.add("commonMain/default/linkdata/module")
+ resources.excludes.add("commonMain/default/linkdata/**/*.knm")
+ resources.excludes.add("nativeMain/default/manifest")
+ resources.excludes.add("nativeMain/default/linkdata/module")
+ resources.excludes.add("nativeMain/default/linkdata/**/*.knm")
+ resources.excludes.add("nonJvmMain/default/manifest")
+ resources.excludes.add("nonJvmMain/default/linkdata/module")
+ resources.excludes.add("nonJvmMain/default/linkdata/**/*.knm")
+ }
+ `;
+
+ // Find the position of 'android {' and add packagingOptions there
+ const androidBlockStart = buildGradleContents.indexOf('android {');
+ if (androidBlockStart !== -1) {
+ const insertPosition = androidBlockStart + 'android {'.length;
+ return (
+ buildGradleContents.slice(0, insertPosition) +
+ '\n' +
+ packagingOptionsBlock +
+ buildGradleContents.slice(insertPosition)
+ );
+ }
+
+ return buildGradleContents;
+}
\ No newline at end of file
diff --git a/demo/www/js/index.js b/demo/www/js/index.js
index f1d9278..ff3ca30 100755
--- a/demo/www/js/index.js
+++ b/demo/www/js/index.js
@@ -34,7 +34,14 @@ var app = {
// Bind any cordova events here. Common events are:
// 'pause', 'resume', etc.
onDeviceReady: function() {
-
+ Jumio.setPreloaderFinishedBlock(
+ function(data) {
+ console.log('All models are preloaded. You may start the SDK now!');
+ }, function(error) {
+ alert(JSON.stringify(error));
+ }
+ );
+ Jumio.preloadIfNeeded()
},
start: function() {
diff --git a/package.json b/package.json
index 6bcc9b0..fb182fa 100755
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "cordova-plugin-jumio-mobilesdk",
- "version": "4.11.0",
+ "version": "4.12.0",
"description": "Jumio Mobile SDK Plugin for Cordova",
"cordova": {
"id": "cordova-plugin-jumio-mobilesdk",
diff --git a/plugin.xml b/plugin.xml
index b3af255..9a2c2f8 100755
--- a/plugin.xml
+++ b/plugin.xml
@@ -1,5 +1,5 @@
-
JumioMobileSDK
@@ -43,7 +43,7 @@
-
+
diff --git a/src/android/JumioMobileSDK.kt b/src/android/JumioMobileSDK.kt
index 643a337..a229d9a 100644
--- a/src/android/JumioMobileSDK.kt
+++ b/src/android/JumioMobileSDK.kt
@@ -9,6 +9,8 @@ import com.jumio.sdk.JumioSDK
import com.jumio.sdk.credentials.JumioCredentialCategory.FACE
import com.jumio.sdk.credentials.JumioCredentialCategory.ID
import com.jumio.sdk.enums.JumioDataCenter
+import com.jumio.sdk.preload.JumioPreloadCallback
+import com.jumio.sdk.preload.JumioPreloader
import com.jumio.sdk.result.JumioIDResult
import com.jumio.sdk.result.JumioResult
import org.apache.cordova.CallbackContext
@@ -20,16 +22,19 @@ import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
-class JumioMobileSDK : CordovaPlugin() {
+class JumioMobileSDK : CordovaPlugin(), JumioPreloadCallback {
companion object {
private const val TAG = "JumioMobileSDK"
private const val PERMISSION_REQUEST_CODE = 301
private const val REQUEST_CODE = 101
private const val ACTION_INIT = "initialize"
private const val ACTION_START = "start"
+ private const val ACTION_SET_PRELOADER_FINISHED_BLOCK = "setPreloaderFinishedBlock"
+ private const val ACTION_PRELOAD_IF_NEEDED = "preloadIfNeeded"
}
private var callbackContext: CallbackContext? = null
+ private var preloaderFinishedCallback: (() -> Unit)? = null
override fun execute(action: String, args: JSONArray, callbackContext: CallbackContext): Boolean {
this.callbackContext = callbackContext
@@ -48,6 +53,20 @@ class JumioMobileSDK : CordovaPlugin() {
result.keepCallback = true
true
}
+ ACTION_SET_PRELOADER_FINISHED_BLOCK -> {
+ setPreloaderFinishedBlock {
+ callbackContext.success()
+ }
+ result = PluginResult(NO_RESULT)
+ result.keepCallback = true
+ true
+ }
+ ACTION_PRELOAD_IF_NEEDED -> {
+ preloadIfNeeded()
+ result = PluginResult(NO_RESULT)
+ result.keepCallback = true
+ true
+ }
else -> {
result = PluginResult(INVALID_ACTION)
callbackContext.error("Invalid Action")
@@ -124,6 +143,24 @@ class JumioMobileSDK : CordovaPlugin() {
cordova.activity.runOnUiThread(runnable)
}
+ private fun setPreloaderFinishedBlock(completion: (() -> Unit)) {
+ with(JumioPreloader) {
+ init(cordova.activity)
+ setCallback(this@JumioMobileSDK)
+ }
+ preloaderFinishedCallback = completion
+ }
+
+ private fun preloadIfNeeded() {
+ with(JumioPreloader) {
+ preloadIfNeeded()
+ }
+ }
+
+ override fun preloadFinished() {
+ preloaderFinishedCallback?.invoke()
+ }
+
// Permissions
private fun checkPermissionsAndStart() {
if (!JumioSDK.hasAllRequiredPermissions(cordova.activity.applicationContext)) {
diff --git a/src/android/plugin.gradle b/src/android/plugin.gradle
index ad66d7b..42231cd 100644
--- a/src/android/plugin.gradle
+++ b/src/android/plugin.gradle
@@ -18,7 +18,7 @@ repositories {
}
ext {
- SDK_VERSION = "4.11.0"
+ SDK_VERSION = "4.12.1"
kotlin_version = "1.9.24"
}
@@ -35,7 +35,7 @@ dependencies {
implementation "com.jumio.android:liveness:${SDK_VERSION}"
//only for the sample code
- implementation "androidx.activity:activity-ktx:1.9.0"
+ implementation "androidx.activity:activity-ktx:1.9.3"
//Kotlin
implementation "androidx.multidex:multidex:2.0.1"
diff --git a/src/ios/JumioMobileSDK.swift b/src/ios/JumioMobileSDK.swift
index e1d793e..5a5b679 100644
--- a/src/ios/JumioMobileSDK.swift
+++ b/src/ios/JumioMobileSDK.swift
@@ -8,7 +8,7 @@ import Jumio
import UIKit
@objc(JumioMobileSDK)
-class JumioMobileSDK: CDVPlugin {
+class JumioMobileSDK: CDVPlugin, JumioPreloaderDelegate {
fileprivate var jumio: Jumio.SDK?
fileprivate var jumioVC: Jumio.ViewController?
fileprivate var callbackId: String?
@@ -74,6 +74,21 @@ class JumioMobileSDK: CDVPlugin {
return true
}
+ @objc(setPreloaderFinishedBlock:) func setPreloaderFinishedBlock(_ command: CDVInvokedUrlCommand) {
+ callbackId = command.callbackId
+
+ Jumio.Preloader.shared.delegate = self
+ }
+
+ @objc(preloadIfNeeded:) func preloadIfNeeded(_ command: CDVInvokedUrlCommand) {
+ Jumio.Preloader.shared.preloadIfNeeded()
+ }
+
+ func jumio(finished: Jumio.Preloader) {
+ let pluginResult = CDVPluginResult(status: CDVCommandStatus_OK, messageAs: [] )
+ commandDelegate.send(pluginResult, callbackId: callbackId)
+ }
+
private func getIDResult(idResult: Jumio.IDResult) -> [String: Any] {
let result: [String: Any?] = [
"selectedCountry": idResult.country,
@@ -441,6 +456,24 @@ extension JumioMobileSDK {
customTheme.scanOverlay.scanBackground = Jumio.Theme.Value(UIColor(hexString: scanOverlayBackground))
}
+ if let scanOverlayLivenessStroke = customizations["scanOverlayLivenessStroke"] as? [String: String?], let light = scanOverlayLivenessStroke["light"] as? String, let dark = scanOverlayLivenessStroke["dark"] as? String {
+ customTheme.scanOverlay.livenessStroke = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
+ } else if let scanOverlayLivenessStroke = customizations["scanOverlayLivenessStroke"] as? String {
+ customTheme.scanOverlay.livenessStroke = Jumio.Theme.Value(UIColor(hexString: scanOverlayLivenessStroke))
+ }
+
+ if let scanOverlayLivenessStrokeAnimation = customizations["scanOverlayLivenessStrokeAnimation"] as? [String: String?], let light = scanOverlayLivenessStrokeAnimation["light"] as? String, let dark = scanOverlayLivenessStrokeAnimation["dark"] as? String {
+ customTheme.scanOverlay.livenessStrokeAnimation = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
+ } else if let scanOverlayLivenessStrokeAnimation = customizations["scanOverlayLivenessStrokeAnimation"] as? String {
+ customTheme.scanOverlay.livenessStrokeAnimation = Jumio.Theme.Value(UIColor(hexString: scanOverlayLivenessStrokeAnimation))
+ }
+
+ if let scanOverlayLivenessStrokeAnimationCompleted = customizations["scanOverlayLivenessStrokeAnimationCompleted"] as? [String: String?], let light = scanOverlayLivenessStrokeAnimationCompleted["light"] as? String, let dark = scanOverlayLivenessStrokeAnimationCompleted["dark"] as? String {
+ customTheme.scanOverlay.livenessStrokeAnimationCompleted = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
+ } else if let scanOverlayLivenessStrokeAnimationCompleted = customizations["scanOverlayLivenessStrokeAnimationCompleted"] as? String {
+ customTheme.scanOverlay.livenessStrokeAnimationCompleted = Jumio.Theme.Value(UIColor(hexString: scanOverlayLivenessStrokeAnimationCompleted))
+ }
+
// NFC
if let nfcPassportCover = customizations["nfcPassportCover"] as? [String: String?], let light = nfcPassportCover["light"] as? String, let dark = nfcPassportCover["dark"] as? String {
customTheme.nfc.passportCover = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
diff --git a/www/JumioMobileSDK.js b/www/JumioMobileSDK.js
index 0cfeb5d..24a37ba 100755
--- a/www/JumioMobileSDK.js
+++ b/www/JumioMobileSDK.js
@@ -25,6 +25,14 @@ function Jumio () {
this.start = function(success, error, customizations) {
exec(success, error, "JumioMobileSDK", "start", [customizations]);
};
+
+ this.setPreloaderFinishedBlock = function(success, error) {
+ exec(success, error, "JumioMobileSDK", "setPreloaderFinishedBlock", []);
+ };
+
+ this.preloadIfNeeded = function(success, error) {
+ exec(success, error, "JumioMobileSDK", "preloadIfNeeded", []);
+ };
}
// /**