├── .gitignore
├── .npmignore
├── DemoApp
├── .gitattributes
├── .gitignore
├── .watchmanconfig
├── .yarnrc.yml
├── Gemfile
├── README.md
├── __tests__
│ ├── index.android.js
│ └── index.ios.js
├── android
│ ├── .gitignore
│ ├── app
│ │ ├── BUCK
│ │ ├── build.gradle
│ │ ├── gradle
│ │ │ └── wrapper
│ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ └── gradle-wrapper.properties
│ │ ├── proguard-rules.pro
│ │ └── src
│ │ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ ├── assets
│ │ │ ├── .gitignore
│ │ │ ├── classifier_on_device_ep_99_float16_quant.enc
│ │ │ └── normalized_ensemble_passports_v2_float16_quant.enc
│ │ │ ├── java
│ │ │ └── com
│ │ │ │ └── demoapp
│ │ │ │ ├── MainActivity.kt
│ │ │ │ └── MainApplication.kt
│ │ │ ├── jni
│ │ │ └── Android.mk
│ │ │ └── res
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ └── values
│ │ │ ├── strings-jumio-sdk.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ ├── build.gradle
│ ├── gradle.properties
│ ├── gradle
│ │ └── wrapper
│ │ │ ├── gradle-wrapper.jar
│ │ │ └── gradle-wrapper.properties
│ ├── gradlew
│ ├── gradlew.bat
│ └── settings.gradle
├── app.json
├── babel.config.js
├── index.js
├── ios
│ ├── .gitignore
│ ├── .xcode.env
│ ├── AppDelegate.swift
│ ├── DemoApp-Bridging-Header.h
│ ├── DemoApp.xcodeproj
│ │ ├── project.pbxproj
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── DemoApp.xcscheme
│ ├── DemoApp.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ ├── DemoApp
│ │ ├── Base.lproj
│ │ │ └── LaunchScreen.xib
│ │ ├── DemoApp.entitlements
│ │ ├── Images.xcassets
│ │ │ ├── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ ├── Info.plist
│ │ └── PrivacyInfo.xcprivacy
│ ├── File.swift
│ ├── Podfile
│ ├── classifier_on_device_ep_99_float16_quant.enc
│ └── normalized_ensemble_passports_v2_float16_quant.enc
├── metro.config.js
└── package.json
├── README.md
├── android
├── build.gradle
├── index.android.js
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── jumio
│ │ └── react
│ │ ├── JumioBaseModule.kt
│ │ ├── JumioModule.kt
│ │ └── JumioPackage.kt
│ └── res
│ └── values
│ └── styles.xml
├── images
├── RN_localization.gif
└── known_issues_xcode13.png
├── ios
├── Jumio-Bridging-Header.h
├── JumioCustomization.swift
├── JumioMobileReactSdk.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── JumioMobileSDK.m
├── JumioMobileSDK.swift
├── JumioReactMobileSdk-Bridging-Header.h
├── JumioReactMobileSdk.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── UIColorExtension.swift
└── react-native-jumio-mobilesdk-Bridging-Header.h
├── package-lock.json
├── package.json
└── react-native-jumio-mobilesdk.podspec
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Files for the ART/Dalvik VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Generated files
12 | bin/
13 | gen/
14 | out/
15 |
16 | # Gradle files
17 | .gradle/
18 | build/
19 |
20 | # Local configuration file (sdk path, etc)
21 | local.properties
22 |
23 | # Proguard folder generated by Eclipse
24 | proguard/
25 |
26 | # Log Files
27 | *.log
28 |
29 | # Android Studio Navigation editor temp files
30 | .navigation/
31 |
32 | # Android Studio captures folder
33 | captures/
34 |
35 | # Intellij
36 | *.iml
37 | .idea/workspace.xml
38 | .idea/tasks.xml
39 | .idea/gradle.xml
40 | .idea/dictionaries
41 | .idea/libraries
42 | .idea/.gitignore
43 | .idea/modules.xml
44 | .idea/runConfigurations.xml
45 | .idea/vcs.xml
46 | android/.idea
47 |
48 | # Keystore files
49 | *.jks
50 |
51 | # External native build folder generated in Android Studio 2.2 and later
52 | .externalNativeBuild
53 |
54 | # Google Services (e.g. APIs or Firebase)
55 | google-services.json
56 |
57 | # Freeline
58 | freeline.py
59 | freeline/
60 | freeline_project_description.json
61 |
62 | # XCode
63 |
64 | *.xcuserstate
65 | **/*.xcuserdatad/**
66 |
67 | # VSCode - Java plugin
68 | .project
69 | org.eclipse.buildship.core.prefs
70 |
71 | node_modules/
72 |
73 | # Misc. OS files
74 | .DS_Store
75 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | DemoApp/
--------------------------------------------------------------------------------
/DemoApp/.gitattributes:
--------------------------------------------------------------------------------
1 | *.pbxproj -text
2 |
--------------------------------------------------------------------------------
/DemoApp/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Xcode
6 | #
7 | build/
8 | *.pbxuser
9 | !default.pbxuser
10 | *.mode1v3
11 | !default.mode1v3
12 | *.mode2v3
13 | !default.mode2v3
14 | *.perspectivev3
15 | *.xcarchive
16 | !default.perspectivev3
17 | xcuserdata
18 | *.xccheckout
19 | *.moved-aside
20 | DerivedData
21 | *.hmap
22 | *.ipa
23 | *.xcuserstate
24 | **/.xcode.env.local
25 |
26 | # Android/IntelliJ
27 | #
28 | build/
29 | .idea
30 | .gradle
31 | local.properties
32 | *.iml
33 | *.hprof
34 | .cxx/
35 | *.keystore
36 | !debug.keystore
37 | .kotlin/
38 |
39 | # node.js
40 | #
41 | node_modules/
42 | npm-debug.log
43 | yarn-error.log
44 |
45 | # fastlane
46 | #
47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
48 | # screenshots whenever they are needed.
49 | # For more information about the recommended setup visit:
50 | # https://docs.fastlane.tools/best-practices/source-control/
51 |
52 | **/fastlane/report.xml
53 | **/fastlane/Preview.html
54 | **/fastlane/screenshots
55 | **/fastlane/test_output
56 |
57 | # Bundle artifact
58 | *.jsbundle
59 |
60 | # Ruby / CocoaPods
61 | **/Pods/
62 | /vendor/bundle/
63 |
64 | # Temporary files created by Metro to check the health of the file watcher
65 | .metro-health-check*
66 |
67 | # testing
68 | /coverage
69 |
70 | # Yarn
71 | .yarn/*
72 | !.yarn/patches
73 | !.yarn/plugins
74 | !.yarn/releases
75 | !.yarn/sdks
76 | !.yarn/versions
--------------------------------------------------------------------------------
/DemoApp/.watchmanconfig:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/DemoApp/.yarnrc.yml:
--------------------------------------------------------------------------------
1 | nodeLinker: node-modules
2 |
3 | yarnPath: .yarn/releases/yarn-3.6.4.cjs
--------------------------------------------------------------------------------
/DemoApp/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
4 | ruby ">= 2.6.10"
5 |
6 | # Exclude problematic versions of cocoapods and activesupport that causes build failures.
7 | gem 'cocoapods', '>= 1.13', '!= 1.15.0', '!= 1.15.1'
8 | gem 'activesupport', '>= 6.1.7.5', '!= 7.1.0'
9 | gem 'xcodeproj', '< 1.26.0'
10 | gem 'concurrent-ruby', '< 1.3.4'
11 |
12 | # Ruby 3.4.0 has removed some libraries from the standard library.
13 | gem 'bigdecimal'
14 | gem 'logger'
15 | gem 'benchmark'
16 | gem 'mutex_m'
--------------------------------------------------------------------------------
/DemoApp/README.md:
--------------------------------------------------------------------------------
1 | # DemoApp for React Native
2 |
3 | ## Usage
4 |
5 | Adjust your credentials in **index.js** file, open a bash and run the following commands:
6 |
7 | ### Both
8 | Required to retrieve all dependencies that are required by this demo app:
9 | ```
10 | npm install
11 | ```
12 |
13 | ### iOS
14 | ```
15 | cd ios
16 | pod install
17 | cd ..
18 | react-native run-ios or react-native run-ios --device
19 | ```
20 |
21 | Jumio SDK dependencies added in version 3.8.0 make it necessary to add the following pre-install hook to the Podfile:
22 | ```
23 | pre_install do |installer|
24 | installer.pod_targets.each do |pod|
25 | puts "Overriding the static_framework? method for #{pod.name}"
26 | def pod.static_framework?;
27 | true
28 | end
29 | def pod.build_type;
30 | Pod::BuildType.static_library
31 | end
32 | end
33 | end
34 | ```
35 | This was added because iProov dependencies __SocketIO__ and __Starscream__ need to be build as dynamic frameworks while React Native are supported only as static libraries. This pre-install hook ensures that the pods added as `dynamic_frameworks` are built as dynamic frameworks, while the other pods are built as static libraries.
36 |
37 | One additional post-install hook needs to be added to the Podfile so that the dependencies are build for distribution:
38 | ```
39 | post_install do |installer|
40 | installer.pods_project.targets.each do |target|
41 | target.build_configurations.each do |config|
42 | config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
43 | end
44 | end
45 |
46 | react_native_post_install(
47 | installer,
48 | config[:reactNativePath],
49 | :mac_catalyst_enabled => false
50 | )
51 | __apply_Xcode_12_5_M1_post_install_workaround(installer)
52 | end
53 | ```
54 |
55 | ### Android
56 | ```
57 | npm run android-windows
58 | // or
59 | react-native run-android
60 | ```
61 |
62 | If you get the error: `Unable to crunch file` on windows add the following line to your `build.gradle` (project):
63 | ```javascript
64 | allprojects {
65 | buildDir = "C:/tmp/${rootProject.name}/${project.name}"
66 | }
67 | ```
68 |
--------------------------------------------------------------------------------
/DemoApp/__tests__/index.android.js:
--------------------------------------------------------------------------------
1 | import 'react-native';
2 | import React from 'react';
3 | import Index from '../index.android.js';
4 |
5 | // Note: test renderer must be required after react-native.
6 | import renderer from 'react-test-renderer';
7 |
8 | it('renders correctly', () => {
9 | const tree = renderer.create(
10 |
11 | );
12 | });
13 |
--------------------------------------------------------------------------------
/DemoApp/__tests__/index.ios.js:
--------------------------------------------------------------------------------
1 | import 'react-native';
2 | import React from 'react';
3 | import Index from '../index.ios.js';
4 |
5 | // Note: test renderer must be required after react-native.
6 | import renderer from 'react-test-renderer';
7 |
8 | it('renders correctly', () => {
9 | const tree = renderer.create(
10 |
11 | );
12 | });
13 |
--------------------------------------------------------------------------------
/DemoApp/android/.gitignore:
--------------------------------------------------------------------------------
1 | # Non-project-specific build files:
2 | build.xml
3 | local.properties
4 | # Ant builds
5 | ant-build
6 | ant-gen
7 | # Eclipse builds
8 | gen
9 | out
10 | # Gradle builds
11 | /build
12 | *.iml
13 | .gradle
14 | /local.properties
15 | /.idea/workspace.xml
16 | /.idea/libraries
17 | .DS_Store
18 | build/
19 | /captures
20 | .externalNativeBuild
21 | /.idea
22 |
--------------------------------------------------------------------------------
/DemoApp/android/app/BUCK:
--------------------------------------------------------------------------------
1 | # To learn about Buck see [Docs](https://buckbuild.com/).
2 | # To run your application with Buck:
3 | # - install Buck
4 | # - `npm start` - to start the packager
5 | # - `cd android`
6 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"`
7 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck
8 | # - `buck install -r android/app` - compile, install and run application
9 | #
10 |
11 | lib_deps = []
12 |
13 | for jarfile in glob(['libs/*.jar']):
14 | name = 'jars__' + jarfile[jarfile.rindex('/') + 1: jarfile.rindex('.jar')]
15 | lib_deps.append(':' + name)
16 | prebuilt_jar(
17 | name = name,
18 | binary_jar = jarfile,
19 | )
20 |
21 | for aarfile in glob(['libs/*.aar']):
22 | name = 'aars__' + aarfile[aarfile.rindex('/') + 1: aarfile.rindex('.aar')]
23 | lib_deps.append(':' + name)
24 | android_prebuilt_aar(
25 | name = name,
26 | aar = aarfile,
27 | )
28 |
29 | android_library(
30 | name = "all-libs",
31 | exported_deps = lib_deps,
32 | )
33 |
34 | android_library(
35 | name = "app-code",
36 | srcs = glob([
37 | "src/main/java/**/*.java",
38 | ]),
39 | deps = [
40 | ":all-libs",
41 | ":build_config",
42 | ":res",
43 | ],
44 | )
45 |
46 | android_build_config(
47 | name = "build_config",
48 | package = "com.demoapp",
49 | )
50 |
51 | android_resource(
52 | name = "res",
53 | package = "com.demoapp",
54 | res = "src/main/res",
55 | )
56 |
57 | android_binary(
58 | name = "app",
59 | keystore = "//android/keystores:debug",
60 | manifest = "src/main/AndroidManifest.xml",
61 | package_type = "debug",
62 | deps = [
63 | ":app-code",
64 | ],
65 | )
66 |
--------------------------------------------------------------------------------
/DemoApp/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: "com.android.application"
2 | apply plugin: "org.jetbrains.kotlin.android"
3 | apply plugin: "com.facebook.react"
4 |
5 | /**
6 | * This is the configuration block to customize your React Native Android app.
7 | * By default you don't need to apply any configuration, just uncomment the lines you need.
8 | */
9 | react {
10 | /* Folders */
11 | // The root of your project, i.e. where "package.json" lives. Default is '../..'
12 | // root = file("../../")
13 | // The folder where the react-native NPM package is. Default is ../../node_modules/react-native
14 | // reactNativeDir = file("../../node_modules/react-native")
15 | // The folder where the react-native Codegen package is. Default is ../../node_modules/@react-native/codegen
16 | // codegenDir = file("../../node_modules/@react-native/codegen")
17 | // The cli.js file which is the React Native CLI entrypoint. Default is ../../node_modules/react-native/cli.js
18 | // cliFile = file("../../node_modules/react-native/cli.js")
19 |
20 | /* Variants */
21 | // The list of variants to that are debuggable. For those we're going to
22 | // skip the bundling of the JS bundle and the assets. By default is just 'debug'.
23 | // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants.
24 | // debuggableVariants = ["liteDebug", "prodDebug"]
25 |
26 | /* Bundling */
27 | // A list containing the node command and its flags. Default is just 'node'.
28 | // nodeExecutableAndArgs = ["node"]
29 | //
30 | // The command to run when bundling. By default is 'bundle'
31 | // bundleCommand = "ram-bundle"
32 | //
33 | // The path to the CLI configuration file. Default is empty.
34 | // bundleConfig = file(../rn-cli.config.js)
35 | //
36 | // The name of the generated asset file containing your JS bundle
37 | // bundleAssetName = "MyApplication.android.bundle"
38 | //
39 | // The entry file for bundle generation. Default is 'index.android.js' or 'index.js'
40 | // entryFile = file("../js/MyApplication.android.js")
41 | //
42 | // A list of extra flags to pass to the 'bundle' commands.
43 | // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle
44 | // extraPackagerArgs = []
45 |
46 | /* Hermes Commands */
47 | // The hermes compiler command to run. By default it is 'hermesc'
48 | // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc"
49 | //
50 | // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
51 | // hermesFlags = ["-O", "-output-source-map"]
52 |
53 | /* Autolinking */
54 | autolinkLibrariesWithApp()
55 | }
56 |
57 | /**
58 | * Set this to true to Run Proguard on Release builds to minify the Java bytecode.
59 | */
60 | def enableProguardInReleaseBuilds = false
61 |
62 | /**
63 | * The preferred build flavor of JavaScriptCore (JSC)
64 | *
65 | * For example, to use the international variant, you can use:
66 | * `def jscFlavor = io.github.react-native-community:jsc-android-intl:2026004.+`
67 | *
68 | * The international variant includes ICU i18n library and necessary data
69 | * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
70 | * give correct results when using with locales other than en-US. Note that
71 | * this variant is about 6MiB larger per architecture than default.
72 | */
73 | def jscFlavor = 'io.github.react-native-community:jsc-android:2026004.+'
74 |
75 | android {
76 | compileSdk 35
77 |
78 | namespace "com.demoapp"
79 | defaultConfig {
80 | applicationId "com.demoapp"
81 | minSdkVersion 24
82 | targetSdkVersion 35
83 | versionCode 1
84 | versionName "1.0"
85 | }
86 | buildTypes {
87 | release {
88 | minifyEnabled enableProguardInReleaseBuilds
89 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
90 | }
91 | }
92 |
93 | packagingOptions {
94 | resources.excludes.add("META-INF/versions/9/OSGI-INF/MANIFEST.MF")
95 | resources.excludes.add("META-INF/kotlin-project-structure-metadata.json")
96 | resources.excludes.add("META-INF/kotlinx_coroutines_core.version")
97 | resources.excludes.add("META-INF/LICENSE.md")
98 | resources.excludes.add("META-INF/LICENSE-notice.md")
99 | resources.excludes.add("commonMain/default/manifest")
100 | resources.excludes.add("commonMain/default/linkdata/module")
101 | resources.excludes.add("commonMain/default/linkdata/**/*.knm")
102 | resources.excludes.add("nativeMain/default/manifest")
103 | resources.excludes.add("nativeMain/default/linkdata/module")
104 | resources.excludes.add("nativeMain/default/linkdata/**/*.knm")
105 | resources.excludes.add("nonJvmMain/default/manifest")
106 | resources.excludes.add("nonJvmMain/default/linkdata/module")
107 | resources.excludes.add("nonJvmMain/default/linkdata/**/*.knm")
108 | }
109 | }
110 |
111 | repositories {
112 | google()
113 | mavenCentral()
114 | gradlePluginPortal()
115 | exclusiveContent {
116 | forRepository {
117 | maven {
118 | url 'https://repo.mobile.jumio.ai'
119 | }
120 | }
121 | filter {
122 | includeGroup "com.jumio.android"
123 | includeGroup "com.iproov.sdk"
124 | }
125 | }
126 | }
127 |
128 | dependencies {
129 | implementation project(':react-native-jumio-mobilesdk')
130 | implementation fileTree(include: ['*.jar'], dir: 'libs')
131 | // The version of react-native is set by the React Native Gradle Plugin
132 | implementation("com.facebook.react:react-android")
133 |
134 | if (hermesEnabled.toBoolean()) {
135 | implementation("com.facebook.react:hermes-android")
136 | } else {
137 | implementation jscFlavor
138 | }
139 | }
--------------------------------------------------------------------------------
/DemoApp/android/app/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jumio/mobile-react/2cba53e402f56e0adf260d0f2fc093b1700c76e8/DemoApp/android/app/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/DemoApp/android/app/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/DemoApp/android/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
19 | # Disabling obfuscation is useful if you collect stack traces from production crashes
20 | # (unless you are using a system that supports de-obfuscate the stack traces).
21 | -dontobfuscate
22 |
23 | # React Native
24 |
25 | # Keep our interfaces so they can be used by other ProGuard rules.
26 | # See http://sourceforge.net/p/proguard/bugs/466/
27 | -keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip
28 | -keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters
29 | -keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip
30 |
31 | # Do not strip any method/class that is annotated with @DoNotStrip
32 | -keep @com.facebook.proguard.annotations.DoNotStrip class *
33 | -keep @com.facebook.common.internal.DoNotStrip class *
34 | -keepclassmembers class * {
35 | @com.facebook.proguard.annotations.DoNotStrip *;
36 | @com.facebook.common.internal.DoNotStrip *;
37 | }
38 |
39 | -keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * {
40 | void set*(***);
41 | *** get*();
42 | }
43 |
44 | -keep class * extends com.facebook.react.bridge.JavaScriptModule { *; }
45 | -keep class * extends com.facebook.react.bridge.NativeModule { *; }
46 | -keepclassmembers,includedescriptorclasses class * { native ; }
47 | -keepclassmembers class * { @com.facebook.react.uimanager.UIProp ; }
48 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp ; }
49 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup ; }
50 | -keep class com.facebook.soloader.** { *; }
51 | -keepclassmembers class com.facebook.soloader.SoLoader {
52 | static ;
53 | }
54 |
55 |
56 | -dontwarn com.facebook.react.**
57 |
58 | # TextLayoutBuilder uses a non-public Android constructor within StaticLayout.
59 | # See libs/proxy/src/main/java/com/facebook/fbui/textlayoutbuilder/proxy for details.
60 | -dontwarn android.text.StaticLayout
61 |
62 | # okhttp
63 |
64 | -keepattributes Signature
65 | -keepattributes *Annotation*
66 | -keep class okhttp3.** { *; }
67 | -keep interface okhttp3.** { *; }
68 | -dontwarn okhttp3.**
69 |
70 | # okio
71 |
72 | -keep class sun.misc.Unsafe { *; }
73 | -dontwarn java.nio.file.*
74 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
75 | -dontwarn okio.**
76 |
77 | # Jumio
78 | -keep class com.jumio.** { *; }
79 | -keep class jumio.** { *; }
80 | # keep constraintlayout.motion classes and members for face help animation
81 | #-keep class androidx.constraintlayout.motion.widget.** { *; }
82 |
83 | #Microblink
84 | -keep class com.microblink.** { *; }
85 | -keep class com.microblink.**$* { *; }
86 |
87 | #IProov
88 | -keep public class com.iproov.sdk.IProov {public *; }
89 |
90 | #JRMT
91 | -keep class org.jmrtd.** { *; }
92 | -keep class net.sf.scuba.** { *; }
93 | -keep class org.bouncycastle.** { *; }
94 | -keep class org.ejbca.** { *; }
95 |
96 | -dontwarn java.nio.**
97 | -dontwarn org.codehaus.**
98 | -dontwarn org.ejbca.**
99 | -dontwarn org.bouncycastle.**
100 | -dontwarn module-info
101 | -dontwarn com.microblink.**
102 | -dontwarn javax.annotation.Nullable
--------------------------------------------------------------------------------
/DemoApp/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
17 |
20 |
21 |
25 |
26 |
27 |
33 |
34 |
35 |
36 |
37 |
38 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
52 |
53 |
54 |
55 |
56 |
57 |
--------------------------------------------------------------------------------
/DemoApp/android/app/src/main/assets/.gitignore:
--------------------------------------------------------------------------------
1 | *.bundle
2 | *.bundle.meta
3 |
--------------------------------------------------------------------------------
/DemoApp/android/app/src/main/assets/classifier_on_device_ep_99_float16_quant.enc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jumio/mobile-react/2cba53e402f56e0adf260d0f2fc093b1700c76e8/DemoApp/android/app/src/main/assets/classifier_on_device_ep_99_float16_quant.enc
--------------------------------------------------------------------------------
/DemoApp/android/app/src/main/assets/normalized_ensemble_passports_v2_float16_quant.enc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jumio/mobile-react/2cba53e402f56e0adf260d0f2fc093b1700c76e8/DemoApp/android/app/src/main/assets/normalized_ensemble_passports_v2_float16_quant.enc
--------------------------------------------------------------------------------
/DemoApp/android/app/src/main/java/com/demoapp/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.demoapp
2 |
3 | import com.facebook.react.ReactActivity
4 | import com.facebook.react.ReactActivityDelegate
5 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
6 | import com.facebook.react.defaults.DefaultReactActivityDelegate
7 |
8 | class MainActivity : ReactActivity() {
9 | /**
10 | * Returns the name of the main component registered from JavaScript. This is used to schedule
11 | * rendering of the component.
12 | */
13 | @Override
14 | override fun getMainComponentName() = "DemoApp";
15 |
16 | /**
17 | * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate]
18 | * which allows you to enable New Architecture with a single boolean flags [fabricEnabled]
19 | */
20 | override fun createReactActivityDelegate() = DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled)
21 | }
--------------------------------------------------------------------------------
/DemoApp/android/app/src/main/java/com/demoapp/MainApplication.kt:
--------------------------------------------------------------------------------
1 | package com.demoapp
2 |
3 | import android.app.Application
4 | import com.facebook.react.PackageList
5 | import com.facebook.react.ReactApplication
6 | import com.facebook.react.ReactHost
7 | import com.facebook.react.ReactNativeHost
8 | import com.facebook.react.ReactPackage
9 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
10 | import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
11 | import com.facebook.react.defaults.DefaultReactNativeHost
12 | import com.facebook.react.soloader.OpenSourceMergedSoMapping
13 | import com.facebook.soloader.SoLoader
14 | import com.jumio.react.JumioPackage
15 |
16 | class MainApplication : Application(), ReactApplication {
17 | override val reactNativeHost: ReactNativeHost =
18 | object : DefaultReactNativeHost(this) {
19 | override fun getPackages(): List =
20 | PackageList(this).packages.apply {
21 | // Packages that cannot be autolinked yet can be added manually here, for example:
22 | add(JumioPackage())
23 | }
24 |
25 | override fun getJSMainModuleName(): String = "index"
26 | override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG
27 | override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
28 | override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED
29 | }
30 | override val reactHost: ReactHost
31 | get() = getDefaultReactHost(applicationContext, reactNativeHost)
32 |
33 | override fun onCreate() {
34 | super.onCreate()
35 | SoLoader.init(this, OpenSourceMergedSoMapping)
36 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
37 | // If you opted-in for the New Architecture, we load the native entry point for this app.
38 | load()
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/DemoApp/android/app/src/main/jni/Android.mk:
--------------------------------------------------------------------------------
1 | THIS_DIR := $(call my-dir)
2 |
3 | include $(REACT_ANDROID_DIR)/Android-prebuilt.mk
4 |
5 | # If you wish to add a custom TurboModule or Fabric component in your app you
6 | # will have to include the following autogenerated makefile.
7 | # include $(GENERATED_SRC_DIR)/codegen/jni/Android.mk
8 | include $(CLEAR_VARS)
9 |
10 | LOCAL_PATH := $(THIS_DIR)
11 |
12 | # You can customize the name of your application .so file here.
13 | LOCAL_MODULE := demoapp_appmodules
14 |
15 | LOCAL_C_INCLUDES := $(LOCAL_PATH)
16 | LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp)
17 | LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
18 |
19 | # If you wish to add a custom TurboModule or Fabric component in your app you
20 | # will have to uncomment those lines to include the generated source
21 | # files from the codegen (placed in $(GENERATED_SRC_DIR)/codegen/jni)
22 | #
23 | # LOCAL_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
24 | # LOCAL_SRC_FILES += $(wildcard $(GENERATED_SRC_DIR)/codegen/jni/*.cpp)
25 | # LOCAL_EXPORT_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
26 |
27 | # Here you should add any native library you wish to depend on.
28 | LOCAL_SHARED_LIBRARIES := \
29 | libfabricjni \
30 | libfbjni \
31 | libfolly_futures \
32 | libfolly_json \
33 | libglog \
34 | libjsi \
35 | libreact_codegen_rncore \
36 | libreact_debug \
37 | libreact_nativemodule_core \
38 | libreact_render_componentregistry \
39 | libreact_render_core \
40 | libreact_render_debug \
41 | libreact_render_graphics \
42 | librrc_view \
43 | libruntimeexecutor \
44 | libturbomodulejsijni \
45 | libyoga
46 |
47 | LOCAL_CFLAGS := -DLOG_TAG=\"ReactNative\" -fexceptions -frtti -std=c++17 -Wall
48 |
49 | include $(BUILD_SHARED_LIBRARY)
--------------------------------------------------------------------------------
/DemoApp/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jumio/mobile-react/2cba53e402f56e0adf260d0f2fc093b1700c76e8/DemoApp/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/DemoApp/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jumio/mobile-react/2cba53e402f56e0adf260d0f2fc093b1700c76e8/DemoApp/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/DemoApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jumio/mobile-react/2cba53e402f56e0adf260d0f2fc093b1700c76e8/DemoApp/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/DemoApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jumio/mobile-react/2cba53e402f56e0adf260d0f2fc093b1700c76e8/DemoApp/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/DemoApp/android/app/src/main/res/values/strings-jumio-sdk.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
14 |
15 |
16 |
113 |
114 |
115 |
143 |
144 |
145 |
194 |
195 |
--------------------------------------------------------------------------------
/DemoApp/android/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | DemoApp
3 |
4 |
--------------------------------------------------------------------------------
/DemoApp/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
13 |
14 |
15 | -->
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
--------------------------------------------------------------------------------
/DemoApp/android/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 | buildscript {
3 | ext {
4 | buildToolsVersion = "35.0.0"
5 | minSdkVersion = 24
6 | compileSdkVersion = 35
7 | }
8 | repositories {
9 | google()
10 | mavenCentral()
11 | gradlePluginPortal()
12 | exclusiveContent {
13 | forRepository {
14 | maven {
15 | url 'https://repo.mobile.jumio.ai'
16 | }
17 | }
18 | filter {
19 | includeGroup "com.jumio.android"
20 | includeGroup "com.iproov.sdk"
21 | }
22 | }
23 | }
24 | dependencies {
25 | classpath("com.android.tools.build:gradle")
26 | // classpath("com.google.gms:google-services:4.2.0")
27 | classpath("com.google.android.gms:play-services-vision:20.1.3")
28 | classpath("com.facebook.react:react-native-gradle-plugin")
29 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
30 | }
31 | }
32 |
33 | apply plugin: "com.facebook.react.rootproject"
--------------------------------------------------------------------------------
/DemoApp/android/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 |
20 | android.useAndroidX=true
21 | android.useDeprecatedNdk=true
22 |
23 | # Use this property to specify which architecture you want to build.
24 | # You can also override it from the CLI using
25 | # ./gradlew -PreactNativeArchitectures=x86_64
26 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
27 |
28 | # Use this property to enable support to the new architecture.
29 | # This will allow you to use TurboModules and the Fabric render in
30 | # your application. You should enable this flag either if you want
31 | # to write custom TurboModules/Fabric components OR use libraries that
32 | # are providing them.
33 | newArchEnabled=false
34 |
35 | # Use this property to enable or disable the Hermes JS engine.
36 | # If set to false, you will be using JSC instead.
37 | hermesEnabled=true
--------------------------------------------------------------------------------
/DemoApp/android/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jumio/mobile-react/2cba53e402f56e0adf260d0f2fc093b1700c76e8/DemoApp/android/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/DemoApp/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Apr 19 12:48:49 EEST 2023
2 | distributionBase=GRADLE_USER_HOME
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
4 | distributionPath=wrapper/dists
5 | zipStorePath=wrapper/dists
6 | zipStoreBase=GRADLE_USER_HOME
7 |
--------------------------------------------------------------------------------
/DemoApp/android/gradlew:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | #
4 | # Copyright © 2015-2021 the original authors.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 | # SPDX-License-Identifier: Apache-2.0
19 | #
20 |
21 | ##############################################################################
22 | #
23 | # Gradle start up script for POSIX generated by Gradle.
24 | #
25 | # Important for running:
26 | #
27 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
28 | # noncompliant, but you have some other compliant shell such as ksh or
29 | # bash, then to run this script, type that shell name before the whole
30 | # command line, like:
31 | #
32 | # ksh Gradle
33 | #
34 | # Busybox and similar reduced shells will NOT work, because this script
35 | # requires all of these POSIX shell features:
36 | # * functions;
37 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
38 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»;
39 | # * compound commands having a testable exit status, especially «case»;
40 | # * various built-in commands including «command», «set», and «ulimit».
41 | #
42 | # Important for patching:
43 | #
44 | # (2) This script targets any POSIX shell, so it avoids extensions provided
45 | # by Bash, Ksh, etc; in particular arrays are avoided.
46 | #
47 | # The "traditional" practice of packing multiple parameters into a
48 | # space-separated string is a well documented source of bugs and security
49 | # problems, so this is (mostly) avoided, by progressively accumulating
50 | # options in "$@", and eventually passing that to Java.
51 | #
52 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
53 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
54 | # see the in-line comments for details.
55 | #
56 | # There are tweaks for specific operating systems such as AIX, CygWin,
57 | # Darwin, MinGW, and NonStop.
58 | #
59 | # (3) This script is generated from the Groovy template
60 | # https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
61 | # within the Gradle project.
62 | #
63 | # You can find Gradle at https://github.com/gradle/gradle/.
64 | #
65 | ##############################################################################
66 |
67 | # Attempt to set APP_HOME
68 |
69 | # Resolve links: $0 may be a link
70 | app_path=$0
71 |
72 | # Need this for daisy-chained symlinks.
73 | while
74 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
75 | [ -h "$app_path" ]
76 | do
77 | ls=$( ls -ld "$app_path" )
78 | link=${ls#*' -> '}
79 | case $link in #(
80 | /*) app_path=$link ;; #(
81 | *) app_path=$APP_HOME$link ;;
82 | esac
83 | done
84 |
85 | # This is normally unused
86 | # shellcheck disable=SC2034
87 | APP_BASE_NAME=${0##*/}
88 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
89 | APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
90 |
91 | # Use the maximum available, or set MAX_FD != -1 to use that value.
92 | MAX_FD=maximum
93 |
94 | warn () {
95 | echo "$*"
96 | } >&2
97 |
98 | die () {
99 | echo
100 | echo "$*"
101 | echo
102 | exit 1
103 | } >&2
104 |
105 | # OS specific support (must be 'true' or 'false').
106 | cygwin=false
107 | msys=false
108 | darwin=false
109 | nonstop=false
110 | case "$( uname )" in #(
111 | CYGWIN* ) cygwin=true ;; #(
112 | Darwin* ) darwin=true ;; #(
113 | MSYS* | MINGW* ) msys=true ;; #(
114 | NONSTOP* ) nonstop=true ;;
115 | esac
116 |
117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
118 |
119 |
120 | # Determine the Java command to use to start the JVM.
121 | if [ -n "$JAVA_HOME" ] ; then
122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
123 | # IBM's JDK on AIX uses strange locations for the executables
124 | JAVACMD=$JAVA_HOME/jre/sh/java
125 | else
126 | JAVACMD=$JAVA_HOME/bin/java
127 | fi
128 | if [ ! -x "$JAVACMD" ] ; then
129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
130 |
131 | Please set the JAVA_HOME variable in your environment to match the
132 | location of your Java installation."
133 | fi
134 | else
135 | JAVACMD=java
136 | if ! command -v java >/dev/null 2>&1
137 | then
138 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
139 |
140 | Please set the JAVA_HOME variable in your environment to match the
141 | location of your Java installation."
142 | fi
143 | fi
144 |
145 | # Increase the maximum file descriptors if we can.
146 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
147 | case $MAX_FD in #(
148 | max*)
149 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
150 | # shellcheck disable=SC2039,SC3045
151 | MAX_FD=$( ulimit -H -n ) ||
152 | warn "Could not query maximum file descriptor limit"
153 | esac
154 | case $MAX_FD in #(
155 | '' | soft) :;; #(
156 | *)
157 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
158 | # shellcheck disable=SC3045
159 | ulimit -n "$MAX_FD" ||
160 | warn "Could not set maximum file descriptor limit to $MAX_FD"
161 | esac
162 | fi
163 |
164 | # Collect all arguments for the java command, stacking in reverse order:
165 | # * args from the command line
166 | # * the main class name
167 | # * -classpath
168 | # * -D...appname settings
169 | # * --module-path (only if needed)
170 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
171 |
172 | # For Cygwin or MSYS, switch paths to Windows format before running java
173 | if "$cygwin" || "$msys" ; then
174 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
175 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
176 |
177 | JAVACMD=$( cygpath --unix "$JAVACMD" )
178 |
179 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
180 | for arg do
181 | if
182 | case $arg in #(
183 | -*) false ;; # don't mess with options #(
184 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
185 | [ -e "$t" ] ;; #(
186 | *) false ;;
187 | esac
188 | then
189 | arg=$( cygpath --path --ignore --mixed "$arg" )
190 | fi
191 | # Roll the args list around exactly as many times as the number of
192 | # args, so each arg winds up back in the position where it started, but
193 | # possibly modified.
194 | #
195 | # NB: a `for` loop captures its iteration list before it begins, so
196 | # changing the positional parameters here affects neither the number of
197 | # iterations, nor the values presented in `arg`.
198 | shift # remove old arg
199 | set -- "$@" "$arg" # push replacement arg
200 | done
201 | fi
202 |
203 |
204 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
205 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
206 |
207 | # Collect all arguments for the java command:
208 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
209 | # and any embedded shellness will be escaped.
210 | # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
211 | # treated as '${Hostname}' itself on the command line.
212 |
213 | set -- \
214 | "-Dorg.gradle.appname=$APP_BASE_NAME" \
215 | -classpath "$CLASSPATH" \
216 | org.gradle.wrapper.GradleWrapperMain \
217 | "$@"
218 |
219 | # Stop when "xargs" is not available.
220 | if ! command -v xargs >/dev/null 2>&1
221 | then
222 | die "xargs is not available"
223 | fi
224 |
225 | # Use "xargs" to parse quoted args.
226 | #
227 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed.
228 | #
229 | # In Bash we could simply go:
230 | #
231 | # readarray ARGS < <( xargs -n1 <<<"$var" ) &&
232 | # set -- "${ARGS[@]}" "$@"
233 | #
234 | # but POSIX shell has neither arrays nor command substitution, so instead we
235 | # post-process each arg (as a line of input to sed) to backslash-escape any
236 | # character that might be a shell metacharacter, then use eval to reverse
237 | # that process (while maintaining the separation between arguments), and wrap
238 | # the whole thing up as a single "set" statement.
239 | #
240 | # This will of course break if any of these variables contains a newline or
241 | # an unmatched quote.
242 | #
243 |
244 | eval "set -- $(
245 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
246 | xargs -n1 |
247 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
248 | tr '\n' ' '
249 | )" '"$@"'
250 |
251 | exec "$JAVACMD" "$@"
--------------------------------------------------------------------------------
/DemoApp/android/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 | @rem SPDX-License-Identifier: Apache-2.0
17 | @rem
18 |
19 | @if "%DEBUG%"=="" @echo off
20 | @rem ##########################################################################
21 | @rem
22 | @rem Gradle startup script for Windows
23 | @rem
24 | @rem ##########################################################################
25 |
26 | @rem Set local scope for the variables with windows NT shell
27 | if "%OS%"=="Windows_NT" setlocal
28 |
29 | set DIRNAME=%~dp0
30 | if "%DIRNAME%"=="" set DIRNAME=.
31 | @rem This is normally unused
32 | set APP_BASE_NAME=%~n0
33 | set APP_HOME=%DIRNAME%
34 |
35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
37 |
38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
40 |
41 | @rem Find java.exe
42 | if defined JAVA_HOME goto findJavaFromJavaHome
43 |
44 | set JAVA_EXE=java.exe
45 | %JAVA_EXE% -version >NUL 2>&1
46 | if %ERRORLEVEL% equ 0 goto execute
47 |
48 | echo. 1>&2
49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
50 | echo. 1>&2
51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
52 | echo location of your Java installation. 1>&2
53 |
54 | goto fail
55 |
56 | :findJavaFromJavaHome
57 | set JAVA_HOME=%JAVA_HOME:"=%
58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
59 |
60 | if exist "%JAVA_EXE%" goto execute
61 |
62 | echo. 1>&2
63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
64 | echo. 1>&2
65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
66 | echo location of your Java installation. 1>&2
67 |
68 | goto fail
69 |
70 | :execute
71 | @rem Setup the command line
72 |
73 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
74 |
75 |
76 | @rem Execute Gradle
77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
78 |
79 | :end
80 | @rem End local scope for the variables with windows NT shell
81 | if %ERRORLEVEL% equ 0 goto mainEnd
82 |
83 | :fail
84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
85 | rem the _cmd.exe /c_ return code!
86 | set EXIT_CODE=%ERRORLEVEL%
87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
89 | exit /b %EXIT_CODE%
90 |
91 | :mainEnd
92 | if "%OS%"=="Windows_NT" endlocal
93 |
94 | :omega
--------------------------------------------------------------------------------
/DemoApp/android/settings.gradle:
--------------------------------------------------------------------------------
1 | pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") }
2 | plugins { id("com.facebook.react.settings") }
3 | extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() }
4 |
5 | rootProject.name = 'DemoApp'
6 | include ':react-native-jumio-mobilesdk'
7 | project(':react-native-jumio-mobilesdk').projectDir = new File(rootProject.projectDir, '../../android')
8 | include ':react-native-jumio-mobilesdk'
9 | project(':react-native-jumio-mobilesdk').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-jumio-mobilesdk/android')
10 |
11 | include ':app'
12 | includeBuild('../node_modules/@react-native/gradle-plugin')
--------------------------------------------------------------------------------
/DemoApp/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "DemoApp",
3 | "displayName": "DemoApp"
4 | }
--------------------------------------------------------------------------------
/DemoApp/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ['module:@react-native/babel-preset'],
3 | };
--------------------------------------------------------------------------------
/DemoApp/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Sample React Native App
3 | * https://github.com/facebook/react-native
4 | * @flow
5 | */
6 |
7 | import React, {Component, useState} from 'react';
8 | import {
9 | AppRegistry,
10 | Button,
11 | Platform,
12 | StyleSheet,
13 | View,
14 | NativeModules,
15 | NativeEventEmitter,
16 | TextInput,
17 | Text
18 | } from 'react-native';
19 | import { LogBox } from 'react-native';
20 |
21 | LogBox.ignoreLogs(['new NativeEventEmitter']);
22 |
23 | const { JumioMobileSDK } = NativeModules;
24 |
25 | var DATACENTER = 'DATACENTER'
26 |
27 | // Jumio SDK
28 | const startJumio = (authorizationToken) => {
29 | JumioMobileSDK.initialize(authorizationToken, DATACENTER);
30 |
31 | // Setup iOS customizations
32 | // JumioMobileSDK.setupCustomizations(
33 | // {
34 | // background: "#AC3D9A",
35 | // primaryColor: "#FF5722",
36 | // loadingCircleIcon: "#F2F233",
37 | // loadingCirclePlain: "#57ffc7",
38 | // loadingCircleGradientStart: "#EC407A",
39 | // loadingCircleGradientEnd: "#bc2e41",
40 | // loadingErrorCircleGradientStart: "#AC3D9A",
41 | // loadingErrorCircleGradientEnd: "#C31322",
42 | // primaryButtonBackground: {"light": "#D900ff00", "dark": "#9Edd9E"}
43 | // }
44 | // );
45 |
46 | JumioMobileSDK.start();
47 | };
48 |
49 | const isDeviceRooted = async () => {
50 | const isRooted = await JumioMobileSDK.isRooted();
51 | console.warn("Device is rooted: " + isRooted)
52 | }
53 |
54 | // Callbacks - (Data is displayed as a warning for demo purposes)
55 | const emitterJumio = new NativeEventEmitter(JumioMobileSDK);
56 | emitterJumio.addListener(
57 | 'EventResult',
58 | (EventResult) => console.warn("EventResult: " + JSON.stringify(EventResult))
59 | );
60 | emitterJumio.addListener(
61 | 'EventError',
62 | (EventError) => console.warn("EventError: " + JSON.stringify(EventError))
63 | );
64 |
65 | const initModelPreloading = () => {
66 | JumioMobileSDK.setPreloaderFinishedBlock(() => {
67 | console.log('All models are preloaded. You may start the SDK now!');
68 | });
69 | JumioMobileSDK.preloadIfNeeded()
70 | };
71 |
72 | initModelPreloading();
73 |
74 | export default class DemoApp extends Component {
75 | render() {
76 | return (
77 |
78 |
79 |
80 | );
81 | }
82 | }
83 |
84 | const AuthTokenInput = () => {
85 | const [authorizationToken, setAuthorizationToken] = useState("");
86 |
87 | const [buttonText, setButtonText] = useState('Click');
88 |
89 | function handleClick() {
90 | setButtonText({DATACENTER});
91 | }
92 |
93 | return (
94 |
95 | setAuthorizationToken(text)}
101 | value={authorizationToken}
102 | />
103 |
144 | );
145 | };
146 |
147 | const styles = StyleSheet.create({
148 | container: {
149 | flex: 1,
150 | justifyContent: 'center',
151 | alignItems: 'center',
152 | backgroundColor: '#F5FCFF',
153 | },
154 | welcome: {
155 | fontSize: 20,
156 | textAlign: 'center',
157 | margin: 10,
158 | },
159 | instructions: {
160 | textAlign: 'center',
161 | color: '#333333',
162 | marginBottom: 5,
163 | },
164 | input: {
165 | width: 240,
166 | height: 40,
167 | marginBottom: 20,
168 | borderWidth: 1,
169 | color: 'black'
170 | },
171 | datacenterButton: {
172 | marginVertical: 5,
173 | justifyContent: 'center',
174 | },
175 | datacenter: {
176 | width: 240,
177 | height: 40,
178 | marginBottom: 20,
179 | marginTop: 20,
180 | borderWidth: 1,
181 | color: '#808080',
182 | justifyContent: 'center'
183 | },
184 | });
185 |
186 | AppRegistry.registerComponent('DemoApp', () => DemoApp);
--------------------------------------------------------------------------------
/DemoApp/ios/.gitignore:
--------------------------------------------------------------------------------
1 | *.mode1v3
2 | *.perspectivev3
3 | *.pbxuser
4 | *.xcarchive
5 | .DS_Store
6 | build/
7 | Pods/
8 |
--------------------------------------------------------------------------------
/DemoApp/ios/.xcode.env:
--------------------------------------------------------------------------------
1 | export NODE_BINARY=$(command -v node)
2 |
--------------------------------------------------------------------------------
/DemoApp/ios/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import React
3 | import React_RCTAppDelegate
4 | import ReactAppDependencyProvider
5 |
6 | @main
7 | class AppDelegate: UIResponder, UIApplicationDelegate {
8 | var window: UIWindow?
9 |
10 | var reactNativeDelegate: ReactNativeDelegate?
11 | var reactNativeFactory: RCTReactNativeFactory?
12 |
13 | func application(
14 | _ application: UIApplication,
15 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
16 | ) -> Bool {
17 | let delegate = ReactNativeDelegate()
18 | let factory = RCTReactNativeFactory(delegate: delegate)
19 | delegate.dependencyProvider = RCTAppDependencyProvider()
20 |
21 | reactNativeDelegate = delegate
22 | reactNativeFactory = factory
23 |
24 | window = UIWindow(frame: UIScreen.main.bounds)
25 |
26 | factory.startReactNative(
27 | withModuleName: "DemoApp",
28 | in: window,
29 | launchOptions: launchOptions
30 | )
31 |
32 | return true
33 | }
34 | }
35 |
36 | class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate {
37 | override func sourceURL(for bridge: RCTBridge) -> URL? {
38 | self.bundleURL()
39 | }
40 |
41 | override func bundleURL() -> URL? {
42 | #if DEBUG
43 | RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
44 | #else
45 | Bundle.main.url(forResource: "main", withExtension: "jsbundle")
46 | #endif
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/DemoApp/ios/DemoApp-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Use this file to import your target's public headers that you would like to expose to Swift.
3 | //
4 |
5 |
--------------------------------------------------------------------------------
/DemoApp/ios/DemoApp.xcodeproj/xcshareddata/xcschemes/DemoApp.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
29 |
35 |
36 |
37 |
43 |
49 |
50 |
51 |
52 |
53 |
58 |
59 |
61 |
67 |
68 |
69 |
70 |
71 |
77 |
78 |
79 |
80 |
81 |
82 |
92 |
94 |
100 |
101 |
102 |
103 |
104 |
105 |
111 |
113 |
119 |
120 |
121 |
122 |
124 |
125 |
128 |
129 |
130 |
--------------------------------------------------------------------------------
/DemoApp/ios/DemoApp.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/DemoApp/ios/DemoApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/DemoApp/ios/DemoApp/Base.lproj/LaunchScreen.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
24 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/DemoApp/ios/DemoApp/DemoApp.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.developer.nfc.readersession.formats
6 |
7 | NDEF
8 | TAG
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/DemoApp/ios/DemoApp/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "scale" : "2x",
6 | "size" : "20x20"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "scale" : "3x",
11 | "size" : "20x20"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "scale" : "2x",
16 | "size" : "29x29"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "scale" : "3x",
21 | "size" : "29x29"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "scale" : "2x",
26 | "size" : "40x40"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "scale" : "3x",
31 | "size" : "40x40"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "scale" : "2x",
36 | "size" : "60x60"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "scale" : "3x",
41 | "size" : "60x60"
42 | },
43 | {
44 | "idiom" : "ios-marketing",
45 | "scale" : "1x",
46 | "size" : "1024x1024"
47 | }
48 | ],
49 | "info" : {
50 | "author" : "xcode",
51 | "version" : 1
52 | }
53 | }
--------------------------------------------------------------------------------
/DemoApp/ios/DemoApp/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/DemoApp/ios/DemoApp/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | DemoApp
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(MARKETING_VERSION)
21 | CFBundleSignature
22 | ????
23 | CFBundleURLTypes
24 |
25 |
26 | CFBundleTypeRole
27 | Editor
28 | CFBundleURLSchemes
29 |
30 | com.jumio.demo-react
31 |
32 |
33 |
34 | CFBundleVersion
35 | 1
36 | LSRequiresIPhoneOS
37 |
38 | NFCReaderUsageDescription
39 | This will allow to scan passports with NFC.
40 | NSAppTransportSecurity
41 |
42 | NSAllowsArbitraryLoads
43 |
44 | NSAllowsLocalNetworking
45 |
46 |
47 | NSCameraUsageDescription
48 | This will allow to take photos of your credentials.
49 | NSLocationWhenInUseUsageDescription
50 |
51 | UILaunchStoryboardName
52 | LaunchScreen
53 | UIRequiredDeviceCapabilities
54 |
55 | armv7
56 |
57 | UISupportedInterfaceOrientations
58 |
59 | UIInterfaceOrientationPortrait
60 | UIInterfaceOrientationLandscapeLeft
61 | UIInterfaceOrientationLandscapeRight
62 |
63 | UIViewControllerBasedStatusBarAppearance
64 |
65 | com.apple.developer.nfc.readersession.iso7816.select-identifiers
66 |
67 | A0000002471001
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/DemoApp/ios/DemoApp/PrivacyInfo.xcprivacy:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | NSPrivacyAccessedAPITypes
6 |
7 |
8 | NSPrivacyAccessedAPIType
9 | NSPrivacyAccessedAPICategoryFileTimestamp
10 | NSPrivacyAccessedAPITypeReasons
11 |
12 | C617.1
13 |
14 |
15 |
16 | NSPrivacyAccessedAPIType
17 | NSPrivacyAccessedAPICategoryUserDefaults
18 | NSPrivacyAccessedAPITypeReasons
19 |
20 | CA92.1
21 |
22 |
23 |
24 | NSPrivacyAccessedAPIType
25 | NSPrivacyAccessedAPICategorySystemBootTime
26 | NSPrivacyAccessedAPITypeReasons
27 |
28 | 35F9.1
29 |
30 |
31 |
32 | NSPrivacyCollectedDataTypes
33 |
34 | NSPrivacyTracking
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/DemoApp/ios/File.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
--------------------------------------------------------------------------------
/DemoApp/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Resolve react_native_pods.rb with node to allow for hoisting
2 | require Pod::Executable.execute_command('node', ['-p',
3 | 'require.resolve(
4 | "react-native/scripts/react_native_pods.rb",
5 | {paths: [process.argv[1]]},
6 | )', __dir__]).strip
7 |
8 | platform :ios, min_ios_version_supported
9 | prepare_react_native_project!
10 |
11 | linkage = ENV['USE_FRAMEWORKS']
12 | if linkage != nil
13 | Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
14 | use_frameworks! :linkage => linkage.to_sym
15 | end
16 |
17 | target "DemoApp" do
18 | config = use_native_modules!
19 |
20 | use_react_native!(
21 | :path => config[:reactNativePath],
22 | # An absolute path to your application root.
23 | :app_path => "#{Pod::Config.instance.installation_root}/.."
24 | )
25 | use_frameworks!
26 |
27 | # make all the other frameworks into static frameworks by overriding the static_framework? function to return true
28 | pre_install do |installer|
29 | installer.pod_targets.each do |pod|
30 | puts "Overriding the static_framework? method for #{pod.name}"
31 | def pod.static_framework?;
32 | true
33 | end
34 | def pod.build_type;
35 | Pod::BuildType.static_library
36 | end
37 | end
38 | end
39 |
40 | post_install do |installer|
41 | installer.pods_project.targets.each do |target|
42 | target.build_configurations.each do |config|
43 | config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
44 | end
45 | end
46 |
47 | react_native_post_install(
48 | installer,
49 | config[:reactNativePath],
50 | :mac_catalyst_enabled => false,
51 | # :ccache_enabled => true
52 | )
53 |
54 | installer.pods_project.targets.each do |target|
55 | target.build_configurations.each do |config|
56 | config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0'
57 | end
58 | end
59 | end
60 | end
61 |
--------------------------------------------------------------------------------
/DemoApp/ios/classifier_on_device_ep_99_float16_quant.enc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jumio/mobile-react/2cba53e402f56e0adf260d0f2fc093b1700c76e8/DemoApp/ios/classifier_on_device_ep_99_float16_quant.enc
--------------------------------------------------------------------------------
/DemoApp/ios/normalized_ensemble_passports_v2_float16_quant.enc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jumio/mobile-react/2cba53e402f56e0adf260d0f2fc093b1700c76e8/DemoApp/ios/normalized_ensemble_passports_v2_float16_quant.enc
--------------------------------------------------------------------------------
/DemoApp/metro.config.js:
--------------------------------------------------------------------------------
1 | const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config');
2 |
3 | /**
4 | * Metro configuration
5 | * https://reactnative.dev/docs/metro
6 | *
7 | * @type {import('@react-native/metro-config').MetroConfig}
8 | */
9 | const config = {};
10 |
11 | module.exports = mergeConfig(getDefaultConfig(__dirname), config);
--------------------------------------------------------------------------------
/DemoApp/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "DemoApp",
3 | "version": "4.13.0",
4 | "private": true,
5 | "scripts": {
6 | "android": "react-native run-android",
7 | "ios": "react-native run-ios",
8 | "lint": "eslint .",
9 | "start": "react-native start",
10 | "test": "jest"
11 | },
12 | "dependencies": {
13 | "metro": "0.81.0",
14 | "react": "19.0.0",
15 | "react-native": "0.79.1",
16 | "react-native-jumio-mobilesdk": "file:../"
17 | },
18 | "devDependencies": {
19 | "@babel/core": "^7.25.2",
20 | "@babel/preset-env": "^7.25.3",
21 | "@babel/runtime": "^7.25.0",
22 | "@react-native-community/cli": "18.0.0",
23 | "@react-native-community/cli-platform-android": "18.0.0",
24 | "@react-native-community/cli-platform-ios": "18.0.0",
25 | "@react-native/babel-preset": "0.79.1",
26 | "@react-native/eslint-config": "0.79.1",
27 | "@react-native/metro-config": "0.79.1",
28 | "@react-native/typescript-config": "0.79.1",
29 | "@types/jest": "^29.5.13",
30 | "@types/react": "^19.0.0",
31 | "@types/react-test-renderer": "^19.0.0",
32 | "eslint": "^8.19.0",
33 | "jest": "^29.6.3",
34 | "prettier": "^2.8.8",
35 | "react-test-renderer": "19.0.0",
36 | "typescript": "5.0.4"
37 | },
38 | "engines": {
39 | "node": ">=18"
40 | }
41 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Plugin for React Native
2 | Official Jumio Mobile SDK plugin for React Native
3 |
4 | This plugin is compatible with version 4.13.0 of the Jumio SDK.
5 | If you have questions, please reach out to your Account Manager or contact [Jumio Support](#support).
6 |
7 | # Table of Contents
8 | - [Compatibility](#compatibility)
9 | - [Setup](#setup)
10 | - [Integration](#integration)
11 | - [iOS](#ios)
12 | - [Android](#ios)
13 | - [Proguard](#proguard)
14 | - [Usage](#usage)
15 | - [Retrieving Information](#retrieving-information)
16 | - [Customization](#customization)
17 | - [Configuration](#configuration)
18 | - [Callbacks](#callbacks)
19 | - [Result Objects](#result-objects)
20 | - [Local Models for ID Verification and Liveness](#local-models-for-id-verification-and-liveness)
21 | - [FAQ](#faq)
22 | - [Face help animation breaks on Android](#face-help-animation-breaks-on-android)
23 | - [iOS Runs on Debug, Crashes on Release Build](#ios-runs-on-debug-crashes-on-release-build)
24 | - [Using iOS Dynamic Frameworks with React Native Sample App](#using-ios-dynamic-frameworks-with-react-native-sample-app)
25 | - [iOS Crashes on Start with Xcode 15](#ios-crashes-on-start-with-xcode-15)
26 | - [iOS Build Fails for React 0.71.2](#ios-build-fails-for-react-0712)
27 | - [iOS Localization](#ios-localization)
28 | - [Support](#support)
29 |
30 | ## Compatibility
31 | We only ensure compatibility with a minimum React Native version of 0.79.1
32 |
33 | ## Setup
34 | Create React Native project and add the Jumio Mobile SDK module to it.
35 |
36 | ```sh
37 | react-native init MyProject
38 | cd MyProject
39 | npm install --save https://github.com/Jumio/mobile-react.git#v4.13.0
40 | cd ios && pod install
41 | ```
42 |
43 | ## Integration
44 |
45 | ### iOS
46 | 1. Add the "**NSCameraUsageDescription**"-key to your Info.plist file.
47 | 2. Your app's deployment target must be at least iOS 13.0
48 |
49 | #### NFC
50 |
51 | Check out the [NFC setup guide](https://github.com/Jumio/mobile-sdk-ios/blob/master/docs/integration_guide.md#nfc-setup).
52 |
53 | #### Digital Identity
54 |
55 | Check out the [Digital Identity setup guide](https://github.com/Jumio/mobile-sdk-ios/blob/master/docs/integration_guide.md#digital-identity-setup).
56 |
57 | #### Device Risk
58 | To include Jumio's Device Risk functionality, you need to add `pod Jumio/DeviceRisk` to your Podfile.
59 |
60 | ### Android
61 | __AndroidManifest__
62 | Open your AndroidManifest.xml file and change `allowBackup` to false.
63 | ```xml
64 |
67 |
68 | ```
69 |
70 | Make sure your compileSdkVersion and buildToolsVersion are high enough.
71 |
72 | ```groovy
73 | android {
74 | compileSdkVersion 33
75 | buildToolsVersion "33.0.0"
76 | ...
77 | }
78 | ```
79 |
80 | __Enable MultiDex__
81 | Follow the Android developers guide: https://developer.android.com/studio/build/multidex.html
82 |
83 | ```groovy
84 | android {
85 | ...
86 | defaultConfig {
87 | ...
88 | multiDexEnabled true
89 | }
90 | }
91 | ```
92 |
93 | __Upgrade Gradle build tools__
94 | The plugin requires at least version 8.0.0 of the Android build tools. This transitively requires and upgrade of the Gradle wrapper to version 8 and an update to Java 11.
95 |
96 | Upgrade build tools version to 8.7.3 in android/build.gradle:
97 |
98 | ```groovy
99 | buildscript {
100 | ...
101 | dependencies {
102 | ...
103 | classpath 'com.android.tools.build:gradle:8.7.3'
104 | }
105 | }
106 | ```
107 |
108 | If necessary, modify the Gradle Wrapper version in android/gradle.wrapper/gradle-wrapper.properties:
109 | ```
110 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
111 | ```
112 |
113 | __Repository__
114 | Add the Jumio Mobile SDK repository:
115 |
116 | ```groovy
117 | exclusiveContent {
118 | forRepository {
119 | maven {
120 | url 'https://repo.mobile.jumio.ai'
121 | }
122 | }
123 | filter {
124 | includeGroup "com.jumio.android"
125 | includeGroup "com.iproov.sdk"
126 | }
127 | }
128 | ```
129 |
130 | #### Proguard
131 | For information on Android Proguard Rules concerning the Jumio SDK, please refer to our [Android guides](https://github.com/Jumio/mobile-sdk-android#proguard).
132 |
133 | ## Usage
134 |
135 | 1. Add __"NativeModules"__ to the import of 'react-native'.
136 |
137 | ```javascript
138 | import {
139 | ...
140 | NativeModules
141 | } from 'react-native';
142 | ```
143 |
144 | 2. Create a variable of your iOS module:
145 |
146 | ```javascript
147 | const { JumioMobileSDK } = NativeModules;
148 | ```
149 |
150 | 3. The SDKs can be initialized with the following calls.
151 |
152 | ```javascript
153 | JumioMobileSDK.initialize(, );
154 | ```
155 |
156 | Datacenter can either be **US**, **EU** or **SG**.
157 | For more information about how to obtain an `AUTHORIZATION_TOKEN`, please refer to our [API Guide](https://jumio.github.io/kyx/integration-guide.html).
158 |
159 | As soon as the SDK is initialized, the SDK is started by the following call.
160 |
161 | ```javascript
162 | JumioMobileSDK.start();
163 | ```
164 |
165 | Optionally, it is possible to check whether a device is rooted / jailbroken with the following method:
166 | ```javascript
167 | const isRooted = await JumioMobileSDK.isRooted();
168 | ```
169 |
170 | ### Retrieving information
171 |
172 | You can listen to events to retrieve the scanned data:
173 |
174 | * `EventResult` for Jumio results.
175 | * `EventError` for Jumio error.
176 |
177 | First add `NativeEventEmitter` to the import from 'react-native' and listen to the events.
178 |
179 | ```javascript
180 | import {
181 | ...
182 | NativeEventEmitter
183 | } from 'react-native';
184 | ```
185 |
186 | The event receives a JSON object with all the data.
187 | The example below shows how to retrieve the information of each emitter as a String:
188 |
189 | ```javascript
190 | const emitterJumio = new NativeEventEmitter(JumioMobileSDK);
191 | emitterJumio.addListener(
192 | 'EventResult',
193 | (EventResult) => console.warn("EventResult: " + JSON.stringify(EventResult))
194 | );
195 | emitterJumio.addListener(
196 | 'EventError',
197 | (EventError) => console.warn("EventError: " + JSON.stringify(EventError))
198 | );
199 | ```
200 |
201 | ## Customization
202 | ### Android
203 | JumioSDK Android appearance can be customized by overriding the custom theme `AppThemeCustomJumio`. A customization example of all values can be found in the [`styles.xml`](DemoApp/android/app/src/main/res/values/styles.xml) of the DemoApp.
204 |
205 | ### iOS
206 | JumioSDK iOS appearance can be customized to your respective needs. You can customize each color based on the device's set appearance, for either Dark mode or Light mode, or you can set a single color for both appearances. Customization is optional and not required.
207 |
208 | You can pass the following customization options to the [`setupCustomizations()`](DemoApp/index.js#L30) function:
209 |
210 | | Customization key |
211 | |:------------------------------------------------|
212 | | facePrimary |
213 | | faceSecondary |
214 | | faceOutline |
215 | | faceAnimationForeground |
216 | | iProovFilterForegroundColor |
217 | | iProovFilterBackgroundColor |
218 | | iProovTitleTextColor |
219 | | iProovCloseButtonTintColor |
220 | | iProovSurroundColor |
221 | | iProovPromptTextColor |
222 | | iProovPromptBackgroundColor |
223 | | genuinePresenceAssuranceReadyOvalStrokeColor |
224 | | genuinePresenceAssuranceNotReadyOvalStrokeColor |
225 | | livenessAssuranceOvalStrokeColor |
226 | | livenessAssuranceCompletedOvalStrokeColor |
227 | | primaryButtonBackground |
228 | | primaryButtonBackgroundPressed |
229 | | primaryButtonBackgroundDisabled |
230 | | primaryButtonForeground |
231 | | primaryButtonForegroundPressed |
232 | | primaryButtonForegroundDisabled |
233 | | primaryButtonOutline |
234 | | secondaryButtonBackground |
235 | | secondaryButtonBackgroundPressed |
236 | | secondaryButtonBackgroundDisabled |
237 | | secondaryButtonForeground |
238 | | secondaryButtonForegroundPressed |
239 | | secondaryButtonForegroundDisabled |
240 | | secondaryButtonOutline |
241 | | bubbleBackground |
242 | | bubbleForeground |
243 | | bubbleBackgroundSelected |
244 | | bubbleOutline |
245 | | loadingCirclePlain |
246 | | loadingCircleGradientStart |
247 | | loadingCircleGradientEnd |
248 | | loadingErrorCircleGradientStart |
249 | | loadingErrorCircleGradientEnd |
250 | | loadingCircleIcon |
251 | | scanOverlay |
252 | | scanOverlayBackground |
253 | | nfcPassportCover |
254 | | nfcPassportPageDark |
255 | | nfcPassportPageLight |
256 | | nfcPassportForeground |
257 | | nfcPhoneCover |
258 | | scanViewTooltipForeground |
259 | | scanViewTooltipBackground |
260 | | scanViewForeground |
261 | | scanViewDocumentShutter |
262 | | scanViewFaceShutter |
263 | | searchBubbleBackground |
264 | | searchBubbleForeground |
265 | | searchBubbleOutline |
266 | | confirmationImageBackground |
267 | | confirmationImageBackgroundBorder |
268 | | confirmationIndicatorActive |
269 | | confirmationIndicatorDefault |
270 | | confirmationImageBorder |
271 | | background |
272 | | navigationIconColor |
273 | | textForegroundColor |
274 | | primaryColor |
275 | | selectionIconForeground |
276 |
277 | All colors are provided with a HEX string in the following formats: `#ff00ff` or `#66ff00ff` if you want to set the alpha level.
278 |
279 | **Customization example**
280 |
281 | Example for setting color based on Dark or Light mode:
282 | ```
283 | JumioMobileSDK.setupCustomizations({
284 | primaryColor: { light:"ffffff", dark:"000000" }
285 | primaryButtonBackground: { light:ffffff, dark:"000000" }
286 | });
287 | ```
288 |
289 | Example for setting same color for both Dark and Light mode:
290 | ```
291 | JumioMobileSDK.setupCustomizations({
292 | primaryColor: "ffffff"
293 | primaryButtonBackground: "ffffff"
294 | });
295 | ```
296 |
297 | ## Configuration
298 | For more information about how to set specific SDK parameters (callbackUrl, userReference, country, ...), please refer to our [API Guide](https://jumio.github.io/kyx/integration-guide.html#request-body).
299 |
300 | ## Callbacks
301 | In oder to get information about result fields, Retrieval API, Delete API, global settings and more, please read our [page with server related information](https://jumio.github.io/kyx/integration-guide.html#callback).
302 |
303 | ## Result Objects
304 | The JSON object with all the extracted data that is returned for the specific products is described in the following subchapters:
305 |
306 | ### EventResult
307 |
308 | | Parameter | Type | Max. length | Description |
309 | |:------------------------|:---------|:------------|:-----------------------------------------------------------------------------------------------------------|
310 | | selectedCountry | String | 3 | [ISO 3166-1 alpha-3](http://en.wikipedia.org/wiki/ISO_3166-1_alpha-3) country code as provided or selected |
311 | | selectedDocumentType | String | 16 | PASSPORT, DRIVER_LICENSE, IDENTITY_CARD or VISA |
312 | | selectedDocumentSubType | String | | Sub type of the scanned ID |
313 | | idNumber | String | 100 | Identification number of the document |
314 | | personalNumber | String | | Personal number of the document |
315 | | issuingDate | Date | | Date of issue |
316 | | expiryDate | Date | | Date of expiry |
317 | | issuingCountry | String | 3 | Country of issue as ([ISO 3166-1 alpha-3](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3)) country code |
318 | | lastName | String | 100 | Last name of the customer |
319 | | firstName | String | 100 | First name of the customer |
320 | | dob | Date | | Date of birth |
321 | | gender | String | 1 | m, f or x |
322 | | originatingCountry | String | 3 | Country of origin as ([ISO 3166-1 alpha-3](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3)) country code |
323 | | addressLine | String | 64 | Street name |
324 | | city | String | 64 | City |
325 | | subdivision | String | 3 | Last three characters of [ISO 3166-2:US](http://en.wikipedia.org/wiki/ISO_3166-2:US) state code |
326 | | postCode | String | 15 | Postal code |
327 | | mrzData | MRZ-DATA | | MRZ data, see table below |
328 | | optionalData1 | String | 50 | Optional field of MRZ line 1 |
329 | | optionalData2 | String | 50 | Optional field of MRZ line 2 |
330 | | placeOfBirth | String | 255 | Place of Birth |
331 |
332 | ### MRZ-Data
333 |
334 | | Parameter | Type | Max. length | Description |
335 | |:--------------------|:-------|:------------|:-------------------------------------------------------------------------------|
336 | | format | String | 8 | MRP, TD1, TD2, CNIS, MRVA, MRVB or UNKNOWN |
337 | | line1 | String | 50 | MRZ line 1 |
338 | | line2 | String | 50 | MRZ line 2 |
339 | | line3 | String | 50 | MRZ line 3 |
340 | | idNumberValid | BOOL | | True if ID number check digit is valid, otherwise false |
341 | | dobValid | BOOL | | True if date of birth check digit is valid, otherwise false |
342 | | expiryDateValid | BOOL | | True if date of expiry check digit is valid or not available, otherwise false |
343 | | personalNumberValid | BOOL | | True if personal number check digit is valid or not available, otherwise false |
344 | | compositeValid | BOOL | | True if composite check digit is valid, otherwise false |
345 |
346 |
347 | ## Local Models for ID Verification and Liveness
348 |
349 | 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.
350 |
351 | ### Preloading models
352 |
353 | 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`.
354 |
355 | ### iOS
356 |
357 | 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.
358 |
359 | You also need to copy those files to the "ios/Assets" folder for React to recognize them.
360 |
361 | ### Android
362 |
363 | 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.
364 |
365 | You need to copy those files to the assets folder of your Android project (Path: "app/src/main/assets/").
366 |
367 |
368 | ## FAQ
369 |
370 | ### Face help animation breaks on Android
371 | If face help animation looks as expected in debug builds, but breaks in release builds, please make sure to include the following rule in your [**Proguard** file](DemoApp/android/app/proguard-rules.pro):
372 | ```
373 | -keep class androidx.constraintlayout.motion.widget.** { *; }
374 | ```
375 |
376 | ### iOS Simulator shows a white-screen, when the Jumio SDK is started
377 | The Jumio SDK does not support the iOS Simulator. Please run the Jumio SDK only on physical devices.
378 |
379 | ### iOS Runs on Debug, Crashes on Release Build
380 | This happens due to Xcode 13 introducing a new option to their __App Store Distribution Options__:
381 |
382 | __"Manage Version and Build Number"__ (see image below)
383 |
384 | If checked, this option changes the version and build number of all content of your app to the overall application version, including third-party frameworks. __This option is enabled by default.__ Please make sure to disable this option when archiving / exporting your application to the App Store. Otherwise, the Jumio SDK version check, which ensures all bundled frameworks are up to date, will fail.
385 |
386 | 
387 |
388 | Alternatively, it is also possible to set the key `manageAppVersionAndBuildNumber` in the __exportOptions.plist__ to `false`:
389 | ```
390 | manageAppVersionAndBuildNumber
391 |
392 | ```
393 |
394 | ### Using iOS Dynamic Frameworks with React Native Sample App
395 | Jumio SDK version 3.8.0 and newer use iProov dependencies that need need to be built as dynamic frameworks.
396 | Since React Native supports only static libraries, a pre-install hook has been added to ensure that pods added as `dynamic_frameworks` are actually built as dynamic frameworks, while all other pods are built as static libraries.
397 |
398 | ```
399 | pre_install do |installer|
400 | installer.pod_targets.each do |pod|
401 | puts "Overriding the static_framework? method for #{pod.name}"
402 | def pod.static_framework?;
403 | true
404 | end
405 | def pod.build_type;
406 | Pod::BuildType.static_library
407 | end
408 | end
409 | end
410 | ```
411 |
412 | Additionally, a post install hook needs to be added to the Podfile to ensure dependencies are build for distribution:
413 | ```
414 | post_install do |installer|
415 | installer.pods_project.targets.each do |target|
416 | if ['iProov', 'DatadogRUM', 'DatadogCore', 'DatadogInternal'].include? target.name
417 | target.build_configurations.each do |config|
418 | config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'YES'
419 | end
420 | end
421 | end
422 | end
423 | ```
424 |
425 | ### iOS Crashes on Start with Xcode 15
426 |
427 | If you are working with Xcode 15 and above, please make sure the following lines have been added to your `Podfile`:
428 |
429 | ```
430 | post_install do |installer|
431 | installer.pods_project.targets.each do |target|
432 | if ['iProov', 'DatadogRUM', 'DatadogCore', 'DatadogInternal'].include? target.name
433 | target.build_configurations.each do |config|
434 | config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0'
435 | end
436 | end
437 | end
438 | end
439 | ```
440 |
441 | Please refer to the iOS section of our [DemoApp guide](DemoApp/README.md#iOS) for additional details.
442 |
443 | ### iOS Build Fails for React 0.71.2
444 | `use_frameworks!` needs to be included in the `Podfile` and properly executed in order for Jumio dynamic frameworks to install correctly.
445 | Make sure [the necessary `pre_install` and `post_install` hooks](#using-ios-dynamic-frameworks-with-react-native-sample-app) have been included.
446 | Also make sure that [Flipper](https://fbflipper.com/) is disabled for your project, since Flipper is not compatible with iOS dynamic frameworks at the moment.
447 |
448 | Please also refer to the [Podfile](DemoApp/ios/Podfile) of our sample application for further details.
449 |
450 | ### iOS Localization
451 | After installing Cocoapods, please localize your iOS application using the languages provided at the following path:
452 | `ios -> Pods -> Jumio -> Localization -> xx.lproj`
453 |
454 | 
455 |
456 | Make sure your `Podfile` is up to date and that new pod versions are installed properly so your `Localizable` files include new strings.
457 | For more information, please refer to our [Changelog](https://github.com/Jumio/mobile-sdk-ios/blob/master/docs/changelog.md) and [Transition Guide](https://github.com/Jumio/mobile-sdk-ios/blob/master/docs/transition_guide.md).
458 |
459 | # Support
460 |
461 | ## Contact
462 | If you have any questions regarding our implementation guide please contact Jumio Customer Service at support@jumio.com or https://support.jumio.com. The Jumio online helpdesk contains a wealth of information regarding our service including demo videos, product descriptions, FAQs and other things that may help to get you started with Jumio. Check it out at: https://support.jumio.com.
463 |
464 | ## Licenses
465 | The source code and software available on this website (“Software”) is provided by Jumio Corp. or its affiliated group companies (“Jumio”) "as is” and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. In no event shall Jumio be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including but not limited to procurement of substitute goods or services, loss of use, data, profits, or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this Software, even if advised of the possibility of such damage.
466 |
467 | In any case, your use of this Software is subject to the terms and conditions that apply to your contractual relationship with Jumio. As regards Jumio’s privacy practices, please see our privacy notice available here: [Privacy Policy](https://www.jumio.com/legal-information/privacy-policy/).
468 |
469 | The software contains third-party open source software. For more information, please see [Android licenses](https://github.com/Jumio/mobile-sdk-android/tree/master/licenses) and [iOS licenses](https://github.com/Jumio/mobile-sdk-ios/tree/master/licenses)
470 |
471 | This software is based in part on the work of the Independent JPEG Group.
472 |
473 | ## Copyright
474 | © Jumio Corp. 268 Lambert Avenue, Palo Alto, CA 94306
475 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = "2.1.0"
3 | repositories {
4 | google()
5 | mavenCentral()
6 | gradlePluginPortal()
7 | }
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:8.7.3'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | classpath("de.undercouch:gradle-download-task:5.0.1")
12 | }
13 | }
14 |
15 | apply plugin: 'com.android.library'
16 | apply plugin: 'kotlin-android'
17 |
18 | android {
19 | compileSdk 35
20 |
21 | defaultConfig {
22 | minSdkVersion 23
23 | targetSdkVersion 35
24 | versionCode 1
25 | versionName "1.0"
26 | ndk {
27 | abiFilters "armeabi-v7a", "x86"
28 | }
29 | multiDexEnabled true
30 | }
31 |
32 | compileOptions {
33 | sourceCompatibility JavaVersion.VERSION_11
34 | targetCompatibility JavaVersion.VERSION_11
35 | }
36 | }
37 |
38 | repositories {
39 | google()
40 | exclusiveContent {
41 | forRepository {
42 | maven {
43 | url 'https://repo.mobile.jumio.ai'
44 | }
45 | }
46 | filter {
47 | includeGroup "com.jumio.android"
48 | includeGroup "com.iproov.sdk"
49 | }
50 | }
51 | }
52 |
53 | ext {
54 | SDK_VERSION = "4.13.0"
55 | }
56 |
57 | dependencies {
58 | implementation fileTree(dir: 'libs', include: '*.jar')
59 |
60 | // Kotlin
61 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.1.0"
62 | // only for the sample code
63 | implementation "androidx.activity:activity-ktx:1.9.3"
64 | implementation "androidx.multidex:multidex:2.0.1"
65 |
66 | // Jumio dependencies
67 | implementation platform("com.jumio.android:bom:${SDK_VERSION}")
68 | implementation "com.jumio.android:core"
69 | implementation "com.jumio.android:docfinder"
70 | implementation "com.jumio.android:nfc"
71 | implementation "com.jumio.android:barcode-mlkit"
72 | implementation "com.jumio.android:iproov"
73 | implementation "com.jumio.android:defaultui"
74 | implementation "com.jumio.android:digital-identity"
75 | implementation "com.jumio.android:liveness"
76 | implementation "com.jumio.android:camerax"
77 |
78 | implementation 'com.facebook.react:react-native:+'
79 | }
80 |
--------------------------------------------------------------------------------
/android/index.android.js:
--------------------------------------------------------------------------------
1 | 'use strict'
2 |
3 | import { NativeModules } from 'react-native'
4 | // name as defined via ReactContextBaseJavaModule's getName
5 | module.exports = NativeModules.JumioMobileSDK
6 |
--------------------------------------------------------------------------------
/android/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
17 |
18 | -keep class net.sf.scuba.smartcards.IsoDepCardService {*;}
19 | -keep class org.jmrtd.** { *; }
20 | -keep class net.sf.scuba.** {*;}
21 | -keep class org.bouncycastle.** {*;}
22 | -keep class org.ejbca.** {*;}
23 |
24 | -dontwarn java.nio.**
25 | -dontwarn org.codehaus.**
26 | -dontwarn org.ejbca.**
27 | -dontwarn org.bouncycastle.**
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/android/src/main/java/com/jumio/react/JumioBaseModule.kt:
--------------------------------------------------------------------------------
1 | package com.jumio.react
2 |
3 | import android.util.Log
4 | import androidx.core.app.ActivityCompat
5 | import com.facebook.react.bridge.Arguments
6 | import com.facebook.react.bridge.ReactApplicationContext
7 | import com.facebook.react.bridge.ReactContextBaseJavaModule
8 | import com.facebook.react.bridge.WritableMap
9 | import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter
10 | import com.jumio.sdk.JumioSDK
11 |
12 | /*
13 | * Copyright (c) 2022. Jumio Corporation All rights reserved.
14 | */
15 | abstract class JumioBaseModule(context: ReactApplicationContext) : ReactContextBaseJavaModule(context) {
16 | companion object {
17 | private const val PERMISSION_REQUEST_CODE = 303
18 | private const val ERROR_KEY = "EventError"
19 | }
20 |
21 | val reactContext = context
22 |
23 | override fun getName() = "JumioMobileSDK"
24 |
25 | override fun canOverrideExistingModule() = true
26 |
27 | // Permissions
28 | fun checkPermissions() =
29 | if (!JumioSDK.hasAllRequiredPermissions(reactContext)) {
30 | //Acquire missing permissions.
31 | val mp = JumioSDK.getMissingPermissions(reactContext)
32 | ActivityCompat.requestPermissions(reactContext.currentActivity!!, mp, PERMISSION_REQUEST_CODE)
33 | //The result is received in MainActivity::onRequestPermissionsResult.
34 | false
35 | } else {
36 | true
37 | }
38 |
39 | fun sendErrorObject(errorCode: String?, errorMsg: String?) {
40 | val errorResult = Arguments.createMap().apply {
41 | putString("errorCode", errorCode ?: "")
42 | putString("errorMessage", errorMsg ?: "")
43 | }
44 | sendEvent(ERROR_KEY, errorResult)
45 | }
46 |
47 | fun showErrorMessage(msg: String?) {
48 | Log.e("Error", msg ?: "")
49 | val errorResult = Arguments.createMap().apply {
50 | putString("errorMessage", msg ?: "")
51 | }
52 | sendEvent(ERROR_KEY, errorResult)
53 | }
54 |
55 | fun sendEvent(eventName: String, params: WritableMap) =
56 | reactApplicationContext.getJSModule(RCTDeviceEventEmitter::class.java)
57 | .emit(eventName, params)
58 | }
--------------------------------------------------------------------------------
/android/src/main/java/com/jumio/react/JumioModule.kt:
--------------------------------------------------------------------------------
1 | package com.jumio.react
2 |
3 | import android.app.Activity
4 | import android.content.Intent
5 | import android.os.Build
6 | import com.facebook.react.bridge.Arguments
7 | import com.facebook.react.bridge.BaseActivityEventListener
8 | import com.facebook.react.bridge.Callback
9 | import com.facebook.react.bridge.Promise
10 | import com.facebook.react.bridge.ReactApplicationContext
11 | import com.facebook.react.bridge.ReactMethod
12 | import com.facebook.react.bridge.ReadableMap
13 | import com.facebook.react.bridge.WritableMap
14 | import com.jumio.defaultui.JumioActivity
15 | import com.jumio.sdk.JumioSDK
16 | import com.jumio.sdk.credentials.JumioCredentialCategory.FACE
17 | import com.jumio.sdk.credentials.JumioCredentialCategory.ID
18 | import com.jumio.sdk.enums.JumioDataCenter
19 | import com.jumio.sdk.preload.JumioPreloadCallback
20 | import com.jumio.sdk.preload.JumioPreloader
21 | import com.jumio.sdk.result.JumioIDResult
22 | import com.jumio.sdk.result.JumioResult
23 |
24 | /*
25 | * Copyright (c) 2022. Jumio Corporation All rights reserved.
26 | */
27 |
28 | class JumioModule(context: ReactApplicationContext) : JumioBaseModule(context), JumioPreloadCallback {
29 | companion object {
30 | private const val REQUEST_CODE = 101
31 | }
32 |
33 | private var preloaderFinishedCallback: Callback? = null
34 |
35 | private val mActivityEventListener =
36 | object : BaseActivityEventListener() {
37 | override fun onActivityResult(activity: Activity?, requestCode: Int, resultCode: Int, data: Intent?) {
38 | if (requestCode == REQUEST_CODE) {
39 | data?.let {
40 | val jumioResult = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
41 | it.getSerializableExtra(JumioActivity.EXTRA_RESULT, JumioResult::class.java)
42 | } else {
43 | @Suppress("DEPRECATION")
44 | it.getSerializableExtra(JumioActivity.EXTRA_RESULT) as JumioResult?
45 | }
46 |
47 | if (jumioResult?.isSuccess == true) sendScanResult(jumioResult) else sendCancelResult(jumioResult)
48 |
49 | reactContext.removeActivityEventListener(this)
50 | }
51 | }
52 | }
53 | }
54 |
55 | @ReactMethod
56 | fun isRooted(promise: Promise) = promise.resolve(JumioSDK.isRooted(reactContext))
57 |
58 | @ReactMethod
59 | fun initialize(authorizationToken: String, dataCenter: String) {
60 | val hasPermissions = checkPermissions()
61 | val jumioDataCenter = getJumioDataCenter(dataCenter)
62 |
63 | when {
64 | !hasPermissions -> showErrorMessage("Missing required app permissions.")
65 | jumioDataCenter == null -> showErrorMessage("Invalid Datacenter value.")
66 | authorizationToken.isEmpty() -> showErrorMessage("Missing required parameters one-time session authorization token.")
67 | else -> {
68 | try {
69 | initSdk(dataCenter, authorizationToken)
70 | } catch (e: Exception) {
71 | showErrorMessage("Error initializing the Jumio SDK: " + e.localizedMessage)
72 | }
73 | }
74 | }
75 | }
76 |
77 | @ReactMethod
78 | fun setupCustomizations(customizations: ReadableMap?) {
79 | }
80 |
81 | @ReactMethod
82 | fun start() {
83 | try {
84 | reactContext.addActivityEventListener(mActivityEventListener)
85 | } catch (e: Exception) {
86 | showErrorMessage("Error starting the Jumio SDK: " + e.localizedMessage)
87 | }
88 | }
89 |
90 | @ReactMethod
91 | fun setPreloaderFinishedBlock(completion: Callback) {
92 | with(JumioPreloader) {
93 | init(reactContext)
94 | setCallback(this@JumioModule)
95 | }
96 | preloaderFinishedCallback = completion
97 | }
98 |
99 | @ReactMethod
100 | fun preloadIfNeeded() {
101 | with(JumioPreloader) {
102 | preloadIfNeeded()
103 | }
104 | }
105 |
106 | override fun preloadFinished() {
107 | preloaderFinishedCallback?.invoke()
108 | }
109 |
110 | private fun initSdk(dataCenter: String, authorizationToken: String) {
111 | val intent = Intent(currentActivity, JumioActivity::class.java).apply {
112 | putExtra(JumioActivity.EXTRA_TOKEN, authorizationToken)
113 | putExtra(JumioActivity.EXTRA_DATACENTER, dataCenter)
114 |
115 | //The following intent extra can be used to customize the Theme of Default UI
116 | putExtra(JumioActivity.EXTRA_CUSTOM_THEME, R.style.AppThemeCustomJumio)
117 | }
118 | currentActivity?.startActivityForResult(intent, REQUEST_CODE)
119 | }
120 |
121 | private fun sendScanResult(jumioResult: JumioResult?) {
122 | val accountId = jumioResult?.accountId
123 | val workflowId = jumioResult?.workflowExecutionId
124 | val credentialInfoList = jumioResult?.credentialInfos
125 |
126 | val result = Arguments.createMap()
127 | val credentialArray = Arguments.createArray()
128 |
129 | credentialInfoList?.let {
130 | accountId?.let { result.putString("accountId", it) }
131 | workflowId?.let { result.putString("workflowId", it) }
132 |
133 | credentialInfoList.forEach {
134 | val eventResultMap = Arguments.createMap().apply {
135 | putString("credentialId", it.id)
136 | putString("credentialCategory", it.category.toString())
137 | }
138 | when (it.category) {
139 | ID -> {
140 | val idResult = jumioResult.getIDResult(it)
141 |
142 | idResult?.let { handleIdResult(idResult, eventResultMap) }
143 | }
144 | FACE -> {
145 | val faceResult = jumioResult.getFaceResult(it)
146 |
147 | faceResult?.passed?.let { passed -> eventResultMap.putString("passed", passed.toString()) }
148 | }
149 | else -> {}
150 | }
151 | credentialArray.pushMap(eventResultMap)
152 | }
153 | result.putArray("credentials", credentialArray)
154 | }
155 | sendEvent("EventResult", result)
156 | }
157 |
158 | private fun handleIdResult(idResult: JumioIDResult, eventResultMap: WritableMap) =
159 | with(idResult) {
160 | eventResultMap.apply {
161 | country?.let { putString("selectedCountry", it) }
162 | idType?.let { putString("selectedDocumentType", it) }
163 | idSubType?.let { putString("selectedDocumentSubType", it) }
164 | documentNumber?.let { putString("idNumber", it) }
165 | personalNumber?.let { putString("personalNumber", it) }
166 | issuingDate?.let { putString("issuingDate", it) }
167 | expiryDate?.let { putString("expiryDate", it) }
168 | issuingCountry?.let { putString("issuingCountry", it) }
169 | lastName?.let { putString("lastName", it) }
170 | firstName?.let { putString("firstName", it) }
171 | gender?.let { putString("gender", it) }
172 | nationality?.let { putString("nationality", it) }
173 | dateOfBirth?.let { putString("dateOfBirth", it) }
174 | address?.let { putString("addressLine", it) }
175 | city?.let { putString("city", it) }
176 | subdivision?.let { putString("subdivision", it) }
177 | postalCode?.let { putString("postCode", it) }
178 | placeOfBirth?.let { putString("placeOfBirth", it) }
179 | mrzLine1?.let { putString("mrzLine1", it) }
180 | mrzLine2?.let { putString("mrzLine2", it) }
181 | mrzLine3?.let { putString("mrzLine3", it) }
182 | }
183 | }
184 |
185 | private fun sendCancelResult(jumioResult: JumioResult?) =
186 | if (jumioResult?.error != null) {
187 | val errorMessage = jumioResult.error!!.message
188 | val errorCode = jumioResult.error!!.code
189 | sendErrorObject(errorCode, errorMessage)
190 | } else {
191 | showErrorMessage("There was a problem extracting the scan result")
192 | }
193 |
194 | private fun getJumioDataCenter(dataCenter: String) = try {
195 | JumioDataCenter.valueOf(dataCenter)
196 | } catch (e: IllegalArgumentException) {
197 | null
198 | }
199 | }
--------------------------------------------------------------------------------
/android/src/main/java/com/jumio/react/JumioPackage.kt:
--------------------------------------------------------------------------------
1 | package com.jumio.react
2 |
3 | import android.view.View
4 | import com.facebook.react.ReactPackage
5 | import com.facebook.react.bridge.NativeModule
6 | import com.facebook.react.bridge.ReactApplicationContext
7 | import com.facebook.react.uimanager.ReactShadowNode
8 | import com.facebook.react.uimanager.ViewManager
9 |
10 | class JumioPackage() : ReactPackage {
11 | override fun createViewManagers(reactContext: ReactApplicationContext): List>> =
12 | emptyList()
13 |
14 | override fun createNativeModules(reactContext: ReactApplicationContext): List =
15 | listOf(JumioModule(reactContext))
16 | }
--------------------------------------------------------------------------------
/android/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Base application theme.
4 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/images/RN_localization.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jumio/mobile-react/2cba53e402f56e0adf260d0f2fc093b1700c76e8/images/RN_localization.gif
--------------------------------------------------------------------------------
/images/known_issues_xcode13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Jumio/mobile-react/2cba53e402f56e0adf260d0f2fc093b1700c76e8/images/known_issues_xcode13.png
--------------------------------------------------------------------------------
/ios/Jumio-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
--------------------------------------------------------------------------------
/ios/JumioCustomization.swift:
--------------------------------------------------------------------------------
1 | import Jumio
2 |
3 | extension JumioMobileSDK {
4 | func customizeSDKColors(customizations: [String: Any?]) -> Jumio.Theme {
5 | var customTheme = Jumio.Theme()
6 |
7 | // Face
8 | if let facePrimary = customizations["facePrimary"] as? [String: String?], let light = facePrimary["light"] as? String, let dark = facePrimary["dark"] as? String {
9 | customTheme.face.primary = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
10 | } else if let facePrimary = customizations["facePrimary"] as? String {
11 | customTheme.face.primary = Jumio.Theme.Value(UIColor(hexString: facePrimary))
12 | }
13 |
14 | if let faceSecondary = customizations["faceSecondary"] as? [String: String?], let light = faceSecondary["light"] as? String, let dark = faceSecondary["dark"] as? String {
15 | customTheme.face.secondary = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
16 | } else if let faceSecondary = customizations["faceSecondary"] as? String {
17 | customTheme.face.secondary = Jumio.Theme.Value(UIColor(hexString: faceSecondary))
18 | }
19 |
20 | if let faceOutline = customizations["faceOutline"] as? [String: String?], let light = faceOutline["light"] as? String, let dark = faceOutline["dark"] as? String {
21 | customTheme.face.outline = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
22 | } else if let faceOutline = customizations["faceOutline"] as? String {
23 | customTheme.face.outline = Jumio.Theme.Value(UIColor(hexString: faceOutline))
24 | }
25 |
26 | // ScanHelp
27 | if let faceAnimationForeground = customizations["faceAnimationForeground"] as? [String: String?], let light = faceAnimationForeground["light"] as? String, let dark = faceAnimationForeground["dark"] as? String {
28 | customTheme.scanHelp.faceAnimationForeground = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
29 | } else if let faceAnimationForeground = customizations["faceAnimationForeground"] as? String {
30 | customTheme.scanHelp.faceAnimationForeground = Jumio.Theme.Value(UIColor(hexString: faceAnimationForeground))
31 | }
32 |
33 | // IProov
34 | if let iProovFilterForegroundColor = customizations["iProovFilterForegroundColor"] as? [String: String?], let light = iProovFilterForegroundColor["light"] as? String, let dark = iProovFilterForegroundColor["dark"] as? String {
35 | customTheme.iProov.filterForegroundColor = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
36 | } else if let iProovFilterForegroundColor = customizations["iProovFilterForegroundColor"] as? String {
37 | customTheme.iProov.filterForegroundColor = Jumio.Theme.Value(UIColor(hexString: iProovFilterForegroundColor))
38 | }
39 |
40 | if let iProovFilterBackgroundColor = customizations["iProovFilterBackgroundColor"] as? [String: String?], let light = iProovFilterBackgroundColor["light"] as? String, let dark = iProovFilterBackgroundColor["dark"] as? String {
41 | customTheme.iProov.filterBackgroundColor = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
42 | } else if let iProovFilterBackgroundColor = customizations["iProovFilterBackgroundColor"] as? String {
43 | customTheme.iProov.filterBackgroundColor = Jumio.Theme.Value(UIColor(hexString: iProovFilterBackgroundColor))
44 | }
45 |
46 | if let iProovTitleTextColor = customizations["iProovTitleTextColor"] as? [String: String?], let light = iProovTitleTextColor["light"] as? String, let dark = iProovTitleTextColor["dark"] as? String {
47 | customTheme.iProov.titleTextColor = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
48 | } else if let iProovTitleTextColor = customizations["iProovTitleTextColor"] as? String {
49 | customTheme.iProov.titleTextColor = Jumio.Theme.Value(UIColor(hexString: iProovTitleTextColor))
50 | }
51 |
52 | if let iProovCloseButtonTintColor = customizations["iProovCloseButtonTintColor"] as? [String: String?], let light = iProovCloseButtonTintColor["light"] as? String, let dark = iProovCloseButtonTintColor["dark"] as? String {
53 | customTheme.iProov.closeButtonTintColor = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
54 | } else if let iProovCloseButtonTintColor = customizations["iProovCloseButtonTintColor"] as? String {
55 | customTheme.iProov.closeButtonTintColor = Jumio.Theme.Value(UIColor(hexString: iProovCloseButtonTintColor))
56 | }
57 |
58 | if let iProovSurroundColor = customizations["iProovSurroundColor"] as? [String: String?], let light = iProovSurroundColor["light"] as? String, let dark = iProovSurroundColor["dark"] as? String {
59 | customTheme.iProov.surroundColor = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
60 | } else if let iProovSurroundColor = customizations["iProovSurroundColor"] as? String {
61 | customTheme.iProov.surroundColor = Jumio.Theme.Value(UIColor(hexString: iProovSurroundColor))
62 | }
63 |
64 | if let iProovPromptTextColor = customizations["iProovPromptTextColor"] as? [String: String?], let light = iProovPromptTextColor["light"] as? String, let dark = iProovPromptTextColor["dark"] as? String {
65 | customTheme.iProov.promptTextColor = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
66 | } else if let iProovPromptTextColor = customizations["iProovPromptTextColor"] as? String {
67 | customTheme.iProov.promptTextColor = Jumio.Theme.Value(UIColor(hexString: iProovPromptTextColor))
68 | }
69 |
70 | if let iProovPromptBackgroundColor = customizations["iProovPromptBackgroundColor"] as? [String: String?], let light = iProovPromptBackgroundColor["light"] as? String, let dark = iProovPromptBackgroundColor["dark"] as? String {
71 | customTheme.iProov.promptBackgroundColor = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
72 | } else if let iProovPromptBackgroundColor = customizations["iProovPromptBackgroundColor"] as? String {
73 | customTheme.iProov.promptBackgroundColor = Jumio.Theme.Value(UIColor(hexString: iProovPromptBackgroundColor))
74 | }
75 |
76 | if let genuinePresenceAssuranceReadyOvalStrokeColor = customizations["genuinePresenceAssuranceReadyOvalStrokeColor"] as? [String: String?], let light = genuinePresenceAssuranceReadyOvalStrokeColor["light"] as? String, let dark = genuinePresenceAssuranceReadyOvalStrokeColor["dark"] as? String {
77 | customTheme.iProov.genuinePresenceAssuranceReadyOvalStrokeColor = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
78 | } else if let genuinePresenceAssuranceReadyOvalStrokeColor = customizations["genuinePresenceAssuranceReadyOvalStrokeColor"] as? String {
79 | customTheme.iProov.genuinePresenceAssuranceReadyOvalStrokeColor = Jumio.Theme.Value(UIColor(hexString: genuinePresenceAssuranceReadyOvalStrokeColor))
80 | }
81 |
82 | if let genuinePresenceAssuranceNotReadyOvalStrokeColor = customizations["genuinePresenceAssuranceNotReadyOvalStrokeColor"] as? [String: String?], let light = genuinePresenceAssuranceNotReadyOvalStrokeColor["light"] as? String, let dark = genuinePresenceAssuranceNotReadyOvalStrokeColor["dark"] as? String {
83 | customTheme.iProov.genuinePresenceAssuranceNotReadyOvalStrokeColor = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
84 | } else if let genuinePresenceAssuranceNotReadyOvalStrokeColor = customizations["genuinePresenceAssuranceNotReadyOvalStrokeColor"] as? String {
85 | customTheme.iProov.genuinePresenceAssuranceNotReadyOvalStrokeColor = Jumio.Theme.Value(UIColor(hexString: genuinePresenceAssuranceNotReadyOvalStrokeColor))
86 | }
87 |
88 | if let livenessAssuranceOvalStrokeColor = customizations["livenessAssuranceOvalStrokeColor"] as? [String: String?], let light = livenessAssuranceOvalStrokeColor["light"] as? String, let dark = livenessAssuranceOvalStrokeColor["dark"] as? String {
89 | customTheme.iProov.livenessAssuranceOvalStrokeColor = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
90 | } else if let livenessAssuranceOvalStrokeColor = customizations["livenessAssuranceOvalStrokeColor"] as? String {
91 | customTheme.iProov.livenessAssuranceOvalStrokeColor = Jumio.Theme.Value(UIColor(hexString: livenessAssuranceOvalStrokeColor))
92 | }
93 |
94 | if let livenessAssuranceCompletedOvalStrokeColor = customizations["livenessAssuranceCompletedOvalStrokeColor"] as? [String: String?], let light = livenessAssuranceCompletedOvalStrokeColor["light"] as? String, let dark = livenessAssuranceCompletedOvalStrokeColor["dark"] as? String {
95 | customTheme.iProov.livenessAssuranceCompletedOvalStrokeColor = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
96 | } else if let livenessAssuranceCompletedOvalStrokeColor = customizations["livenessAssuranceCompletedOvalStrokeColor"] as? String {
97 | customTheme.iProov.livenessAssuranceCompletedOvalStrokeColor = Jumio.Theme.Value(UIColor(hexString: livenessAssuranceCompletedOvalStrokeColor))
98 | }
99 |
100 | // Primary & Secondry Buttons
101 | if let primaryButtonBackground = customizations["primaryButtonBackground"] as? [String: String?], let light = primaryButtonBackground["light"] as? String, let dark = primaryButtonBackground["dark"] as? String {
102 | customTheme.primaryButton.background = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
103 | } else if let primaryButtonBackground = customizations["primaryButtonBackground"] as? String {
104 | customTheme.primaryButton.background = Jumio.Theme.Value(UIColor(hexString: primaryButtonBackground))
105 | }
106 |
107 | if let primaryButtonBackgroundPressed = customizations["primaryButtonBackgroundPressed"] as? [String: String?], let light = primaryButtonBackgroundPressed["light"] as? String, let dark = primaryButtonBackgroundPressed["dark"] as? String {
108 | customTheme.primaryButton.backgroundPressed = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
109 | } else if let primaryButtonBackgroundPressed = customizations["primaryButtonBackgroundPressed"] as? String {
110 | customTheme.primaryButton.backgroundPressed = Jumio.Theme.Value(UIColor(hexString: primaryButtonBackgroundPressed))
111 | }
112 |
113 | if let primaryButtonBackgroundDisabled = customizations["primaryButtonBackgroundDisabled"] as? [String: String?], let light = primaryButtonBackgroundDisabled["light"] as? String, let dark = primaryButtonBackgroundDisabled["dark"] as? String {
114 | customTheme.primaryButton.backgroundDisabled = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
115 | } else if let primaryButtonBackgroundDisabled = customizations["primaryButtonBackgroundDisabled"] as? String {
116 | customTheme.primaryButton.backgroundDisabled = Jumio.Theme.Value(UIColor(hexString: primaryButtonBackgroundDisabled))
117 | }
118 |
119 | if let primaryButtonForeground = customizations["primaryButtonForeground"] as? [String: String?], let light = primaryButtonForeground["light"] as? String, let dark = primaryButtonForeground["dark"] as? String {
120 | customTheme.primaryButton.foreground = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
121 | } else if let primaryButtonForeground = customizations["primaryButtonForeground"] as? String {
122 | customTheme.primaryButton.foreground = Jumio.Theme.Value(UIColor(hexString: primaryButtonForeground))
123 | }
124 |
125 | if let primaryButtonForegroundPressed = customizations["primaryButtonForegroundPressed"] as? [String: String?], let light = primaryButtonForegroundPressed["light"] as? String, let dark = primaryButtonForegroundPressed["dark"] as? String {
126 | customTheme.primaryButton.foregroundPressed = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
127 | } else if let primaryButtonForegroundPressed = customizations["primaryButtonForegroundPressed"] as? String {
128 | customTheme.primaryButton.foregroundPressed = Jumio.Theme.Value(UIColor(hexString: primaryButtonForegroundPressed))
129 | }
130 |
131 | if let primaryButtonForegroundDisabled = customizations["primaryButtonForegroundDisabled"] as? [String: String?], let light = primaryButtonForegroundDisabled["light"] as? String, let dark = primaryButtonForegroundDisabled["dark"] as? String {
132 | customTheme.primaryButton.foregroundDisabled = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
133 | } else if let primaryButtonForegroundDisabled = customizations["primaryButtonForegroundDisabled"] as? String {
134 | customTheme.primaryButton.foregroundDisabled = Jumio.Theme.Value(UIColor(hexString: primaryButtonForegroundDisabled))
135 | }
136 |
137 | if let primaryButtonOutline = customizations["primaryButtonOutline"] as? [String: String?], let light = primaryButtonOutline["light"] as? String, let dark = primaryButtonOutline["dark"] as? String {
138 | customTheme.primaryButton.outline = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
139 | } else if let primaryButtonOutline = customizations["primaryButtonOutline"] as? String {
140 | customTheme.primaryButton.outline = Jumio.Theme.Value(UIColor(hexString: primaryButtonOutline))
141 | }
142 |
143 | if let secondaryButtonBackground = customizations["secondaryButtonBackground"] as? [String: String?], let light = secondaryButtonBackground["light"] as? String, let dark = secondaryButtonBackground["dark"] as? String {
144 | customTheme.secondaryButton.background = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
145 | } else if let secondaryButtonBackground = customizations["secondaryButtonBackground"] as? String {
146 | customTheme.secondaryButton.background = Jumio.Theme.Value(UIColor(hexString: secondaryButtonBackground))
147 | }
148 |
149 | if let secondaryButtonBackgroundPressed = customizations["secondaryButtonBackgroundPressed"] as? [String: String?], let light = secondaryButtonBackgroundPressed["light"] as? String, let dark = secondaryButtonBackgroundPressed["dark"] as? String {
150 | customTheme.secondaryButton.backgroundPressed = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
151 | } else if let secondaryButtonBackgroundPressed = customizations["secondaryButtonBackgroundPressed"] as? String {
152 | customTheme.secondaryButton.backgroundPressed = Jumio.Theme.Value(UIColor(hexString: secondaryButtonBackgroundPressed))
153 | }
154 |
155 | if let secondaryButtonBackgroundDisabled = customizations["secondaryButtonBackgroundDisabled"] as? [String: String?], let light = secondaryButtonBackgroundDisabled["light"] as? String, let dark = secondaryButtonBackgroundDisabled["dark"] as? String {
156 | customTheme.secondaryButton.backgroundDisabled = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
157 | } else if let secondaryButtonBackgroundDisabled = customizations["secondaryButtonBackgroundDisabled"] as? String {
158 | customTheme.secondaryButton.backgroundDisabled = Jumio.Theme.Value(UIColor(hexString: secondaryButtonBackgroundDisabled))
159 | }
160 |
161 | if let secondaryButtonForeground = customizations["secondaryButtonForeground"] as? [String: String?], let light = secondaryButtonForeground["light"] as? String, let dark = secondaryButtonForeground["dark"] as? String {
162 | customTheme.secondaryButton.foreground = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
163 | } else if let secondaryButtonForeground = customizations["secondaryButtonForeground"] as? String {
164 | customTheme.secondaryButton.foreground = Jumio.Theme.Value(UIColor(hexString: secondaryButtonForeground))
165 | }
166 |
167 | if let secondaryButtonForegroundPressed = customizations["secondaryButtonForegroundPressed"] as? [String: String?], let light = secondaryButtonForegroundPressed["light"] as? String, let dark = secondaryButtonForegroundPressed["dark"] as? String {
168 | customTheme.secondaryButton.foregroundPressed = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
169 | } else if let secondaryButtonForegroundPressed = customizations["secondaryButtonForegroundPressed"] as? String {
170 | customTheme.secondaryButton.foregroundPressed = Jumio.Theme.Value(UIColor(hexString: secondaryButtonForegroundPressed))
171 | }
172 |
173 | if let secondaryButtonForegroundDisabled = customizations["secondaryButtonForegroundDisabled"] as? [String: String?], let light = secondaryButtonForegroundDisabled["light"] as? String, let dark = secondaryButtonForegroundDisabled["dark"] as? String {
174 | customTheme.secondaryButton.foregroundDisabled = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
175 | } else if let secondaryButtonForegroundDisabled = customizations["secondaryButtonForegroundDisabled"] as? String {
176 | customTheme.secondaryButton.foregroundDisabled = Jumio.Theme.Value(UIColor(hexString: secondaryButtonForegroundDisabled))
177 | }
178 |
179 | if let secondaryButtonOutline = customizations["secondaryButtonOutline"] as? [String: String?], let light = secondaryButtonOutline["light"] as? String, let dark = secondaryButtonOutline["dark"] as? String {
180 | customTheme.secondaryButton.outline = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
181 | } else if let secondaryButtonOutline = customizations["secondaryButtonOutline"] as? String {
182 | customTheme.secondaryButton.outline = Jumio.Theme.Value(UIColor(hexString: secondaryButtonOutline))
183 | }
184 |
185 | // Bubble, Circle and Selection Icon
186 | if let bubbleBackground = customizations["bubbleBackground"] as? [String: String?], let light = bubbleBackground["light"] as? String, let dark = bubbleBackground["dark"] as? String {
187 | customTheme.bubble.background = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
188 | } else if let bubbleBackground = customizations["bubbleBackground"] as? String {
189 | customTheme.bubble.background = Jumio.Theme.Value(UIColor(hexString: bubbleBackground))
190 | }
191 |
192 | if let bubbleForeground = customizations["bubbleForeground"] as? [String: String?], let light = bubbleForeground["light"] as? String, let dark = bubbleForeground["dark"] as? String {
193 | customTheme.bubble.foreground = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
194 | } else if let bubbleForeground = customizations["bubbleForeground"] as? String {
195 | customTheme.bubble.foreground = Jumio.Theme.Value(UIColor(hexString: bubbleForeground))
196 | }
197 |
198 | if let bubbleBackgroundSelected = customizations["bubbleBackgroundSelected"] as? [String: String?], let light = bubbleBackgroundSelected["light"] as? String, let dark = bubbleBackgroundSelected["dark"] as? String {
199 | customTheme.bubble.backgroundSelected = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
200 | } else if let bubbleBackgroundSelected = customizations["bubbleBackgroundSelected"] as? String {
201 | customTheme.bubble.backgroundSelected = Jumio.Theme.Value(UIColor(hexString: bubbleBackgroundSelected))
202 | }
203 |
204 | if let bubbleOutline = customizations["bubbleOutline"] as? [String: String?], let light = bubbleOutline["light"] as? String, let dark = bubbleOutline["dark"] as? String {
205 | customTheme.bubble.outline = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
206 | } else if let bubbleOutline = customizations["bubbleOutline"] as? String {
207 | customTheme.bubble.outline = Jumio.Theme.Value(UIColor(hexString: bubbleOutline))
208 | }
209 |
210 | // Loading, Error
211 | if let loadingCirclePlain = customizations["loadingCirclePlain"] as? [String: String?], let light = loadingCirclePlain["light"] as? String, let dark = loadingCirclePlain["dark"] as? String {
212 | customTheme.loading.circlePlain = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
213 | } else if let loadingCirclePlain = customizations["loadingCirclePlain"] as? String {
214 | customTheme.loading.circlePlain = Jumio.Theme.Value(UIColor(hexString: loadingCirclePlain))
215 | }
216 |
217 | if let loadingCircleGradientStart = customizations["loadingCircleGradientStart"] as? [String: String?], let light = loadingCircleGradientStart["light"] as? String, let dark = loadingCircleGradientStart["dark"] as? String {
218 | customTheme.loading.loadingCircleGradientStart = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
219 | } else if let loadingCircleGradientStart = customizations["loadingCircleGradientStart"] as? String {
220 | customTheme.loading.loadingCircleGradientStart = Jumio.Theme.Value(UIColor(hexString: loadingCircleGradientStart))
221 | }
222 |
223 | if let loadingCircleGradientEnd = customizations["loadingCircleGradientEnd"] as? [String: String?], let light = loadingCircleGradientEnd["light"] as? String, let dark = loadingCircleGradientEnd["dark"] as? String {
224 | customTheme.loading.loadingCircleGradientEnd = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
225 | } else if let loadingCircleGradientEnd = customizations["loadingCircleGradientEnd"] as? String {
226 | customTheme.loading.loadingCircleGradientEnd = Jumio.Theme.Value(UIColor(hexString: loadingCircleGradientEnd))
227 | }
228 |
229 | if let loadingErrorCircleGradientStart = customizations["loadingErrorCircleGradientStart"] as? [String: String?], let light = loadingErrorCircleGradientStart["light"] as? String, let dark = loadingErrorCircleGradientStart["dark"] as? String {
230 | customTheme.loading.errorCircleGradientStart = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
231 | } else if let loadingErrorCircleGradientStart = customizations["loadingErrorCircleGradientStart"] as? String {
232 | customTheme.loading.errorCircleGradientStart = Jumio.Theme.Value(UIColor(hexString: loadingErrorCircleGradientStart))
233 | }
234 |
235 | if let loadingErrorCircleGradientEnd = customizations["loadingErrorCircleGradientEnd"] as? [String: String?], let light = loadingErrorCircleGradientEnd["light"] as? String, let dark = loadingErrorCircleGradientEnd["dark"] as? String {
236 | customTheme.loading.errorCircleGradientEnd = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
237 | } else if let loadingErrorCircleGradientEnd = customizations["loadingErrorCircleGradientEnd"] as? String {
238 | customTheme.loading.errorCircleGradientEnd = Jumio.Theme.Value(UIColor(hexString: loadingErrorCircleGradientEnd))
239 | }
240 |
241 | if let loadingCircleIcon = customizations["loadingCircleIcon"] as? [String: String?], let light = loadingCircleIcon["light"] as? String, let dark = loadingCircleIcon["dark"] as? String {
242 | customTheme.loading.circleIcon = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
243 | } else if let loadingCircleIcon = customizations["loadingCircleIcon"] as? String {
244 | customTheme.loading.circleIcon = Jumio.Theme.Value(UIColor(hexString: loadingCircleIcon))
245 | }
246 |
247 | // Scan Overlay
248 | if let scanOverlay = customizations["scanOverlay"] as? [String: String?], let light = scanOverlay["light"] as? String, let dark = scanOverlay["dark"] as? String {
249 | customTheme.scanOverlay.scanOverlay = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
250 | } else if let scanOverlay = customizations["scanOverlay"] as? String {
251 | customTheme.scanOverlay.scanOverlay = Jumio.Theme.Value(UIColor(hexString: scanOverlay))
252 | }
253 |
254 | if let scanOverlayBackground = customizations["scanOverlayBackground"] as? [String: String?], let light = scanOverlayBackground["light"] as? String, let dark = scanOverlayBackground["dark"] as? String {
255 | customTheme.scanOverlay.scanBackground = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
256 | } else if let scanOverlayBackground = customizations["scanOverlayBackground"] as? String {
257 | customTheme.scanOverlay.scanBackground = Jumio.Theme.Value(UIColor(hexString: scanOverlayBackground))
258 | }
259 |
260 | if let scanOverlayLivenessStroke = customizations["scanOverlayLivenessStroke"] as? [String: String?], let light = scanOverlayLivenessStroke["light"] as? String, let dark = scanOverlayLivenessStroke["dark"] as? String {
261 | customTheme.scanOverlay.livenessStroke = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
262 | } else if let scanOverlayLivenessStroke = customizations["scanOverlayLivenessStroke"] as? String {
263 | customTheme.scanOverlay.livenessStroke = Jumio.Theme.Value(UIColor(hexString: scanOverlayLivenessStroke))
264 | }
265 |
266 | if let scanOverlayLivenessStrokeAnimation = customizations["scanOverlayLivenessStrokeAnimation"] as? [String: String?], let light = scanOverlayLivenessStrokeAnimation["light"] as? String, let dark = scanOverlayLivenessStrokeAnimation["dark"] as? String {
267 | customTheme.scanOverlay.livenessStrokeAnimation = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
268 | } else if let scanOverlayLivenessStrokeAnimation = customizations["scanOverlayLivenessStrokeAnimation"] as? String {
269 | customTheme.scanOverlay.livenessStrokeAnimation = Jumio.Theme.Value(UIColor(hexString: scanOverlayLivenessStrokeAnimation))
270 | }
271 |
272 | if let scanOverlayLivenessStrokeAnimationCompleted = customizations["scanOverlayLivenessStrokeAnimationCompleted"] as? [String: String?], let light = scanOverlayLivenessStrokeAnimationCompleted["light"] as? String, let dark = scanOverlayLivenessStrokeAnimationCompleted["dark"] as? String {
273 | customTheme.scanOverlay.livenessStrokeAnimationCompleted = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
274 | } else if let scanOverlayLivenessStrokeAnimationCompleted = customizations["scanOverlayLivenessStrokeAnimationCompleted"] as? String {
275 | customTheme.scanOverlay.livenessStrokeAnimationCompleted = Jumio.Theme.Value(UIColor(hexString: scanOverlayLivenessStrokeAnimationCompleted))
276 | }
277 |
278 | // NFC
279 | if let nfcPassportCover = customizations["nfcPassportCover"] as? [String: String?], let light = nfcPassportCover["light"] as? String, let dark = nfcPassportCover["dark"] as? String {
280 | customTheme.nfc.passportCover = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
281 | } else if let nfcPassportCover = customizations["nfcPassportCover"] as? String {
282 | customTheme.nfc.passportCover = Jumio.Theme.Value(UIColor(hexString: nfcPassportCover))
283 | }
284 |
285 | if let nfcPassportPageDark = customizations["nfcPassportPageDark"] as? [String: String?], let light = nfcPassportPageDark["light"] as? String, let dark = nfcPassportPageDark["dark"] as? String {
286 | customTheme.nfc.passportPageDark = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
287 | } else if let nfcPassportPageDark = customizations["nfcPassportPageDark"] as? String {
288 | customTheme.nfc.passportPageDark = Jumio.Theme.Value(UIColor(hexString: nfcPassportPageDark))
289 | }
290 |
291 | if let nfcPassportPageLight = customizations["nfcPassportPageLight"] as? [String: String?], let light = nfcPassportPageLight["light"] as? String, let dark = nfcPassportPageLight["dark"] as? String {
292 | customTheme.nfc.passportPageLight = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
293 | } else if let nfcPassportPageLight = customizations["nfcPassportPageLight"] as? String {
294 | customTheme.nfc.passportPageLight = Jumio.Theme.Value(UIColor(hexString: nfcPassportPageLight))
295 | }
296 |
297 | if let nfcPassportForeground = customizations["nfcPassportForeground"] as? [String: String?], let light = nfcPassportForeground["light"] as? String, let dark = nfcPassportForeground["dark"] as? String {
298 | customTheme.nfc.passportForeground = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
299 | } else if let nfcPassportForeground = customizations["nfcPassportForeground"] as? String {
300 | customTheme.nfc.passportForeground = Jumio.Theme.Value(UIColor(hexString: nfcPassportForeground))
301 | }
302 |
303 | if let nfcPhoneCover = customizations["nfcPhoneCover"] as? [String: String?], let light = nfcPhoneCover["light"] as? String, let dark = nfcPhoneCover["dark"] as? String {
304 | customTheme.nfc.phoneCover = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
305 | } else if let nfcPhoneCover = customizations["nfcPhoneCover"] as? String {
306 | customTheme.nfc.phoneCover = Jumio.Theme.Value(UIColor(hexString: nfcPhoneCover))
307 | }
308 |
309 | // ScanView
310 | if let scanViewTooltipForeground = customizations["scanViewTooltipForeground"] as? [String: String?], let light = scanViewTooltipForeground["light"] as? String, let dark = scanViewTooltipForeground["dark"] as? String {
311 | customTheme.scanView.tooltipForeground = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
312 | } else if let scanViewTooltipForeground = customizations["scanViewTooltipForeground"] as? String {
313 | customTheme.scanView.tooltipForeground = Jumio.Theme.Value(UIColor(hexString: scanViewTooltipForeground))
314 | }
315 |
316 | if let scanViewTooltipBackground = customizations["scanViewTooltipBackground"] as? [String: String?], let light = scanViewTooltipBackground["light"] as? String, let dark = scanViewTooltipBackground["dark"] as? String {
317 | customTheme.scanView.tooltipBackground = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
318 | } else if let scanViewTooltipBackground = customizations["scanViewTooltipBackground"] as? String {
319 | customTheme.scanView.tooltipBackground = Jumio.Theme.Value(UIColor(hexString: scanViewTooltipBackground))
320 | }
321 |
322 | if let scanViewForeground = customizations["scanViewForeground"] as? [String: String?], let light = scanViewForeground["light"] as? String, let dark = scanViewForeground["dark"] as? String {
323 | customTheme.scanView.foreground = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
324 | } else if let scanViewForeground = customizations["scanViewForeground"] as? String {
325 | customTheme.scanView.foreground = Jumio.Theme.Value(UIColor(hexString: scanViewForeground))
326 | }
327 |
328 | if let scanViewDocumentShutter = customizations["scanViewDocumentShutter"] as? [String: String?], let light = scanViewDocumentShutter["light"] as? String, let dark = scanViewDocumentShutter["dark"] as? String {
329 | customTheme.scanView.documentShutter = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
330 | } else if let scanViewDocumentShutter = customizations["scanViewDocumentShutter"] as? String {
331 | customTheme.scanView.documentShutter = Jumio.Theme.Value(UIColor(hexString: scanViewDocumentShutter))
332 | }
333 |
334 | if let scanViewFaceShutter = customizations["scanViewFaceShutter"] as? [String: String?], let light = scanViewFaceShutter["light"] as? String, let dark = scanViewFaceShutter["dark"] as? String {
335 | customTheme.scanView.faceShutter = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
336 | } else if let scanViewFaceShutter = customizations["scanViewFaceShutter"] as? String {
337 | customTheme.scanView.faceShutter = Jumio.Theme.Value(UIColor(hexString: scanViewFaceShutter))
338 | }
339 |
340 | // Search Bubble
341 | if let searchBubbleBackground = customizations["searchBubbleBackground"] as? [String: String?], let light = searchBubbleBackground["light"] as? String, let dark = searchBubbleBackground["dark"] as? String {
342 | customTheme.searchBubble.background = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
343 | } else if let searchBubbleBackground = customizations["searchBubbleBackground"] as? String {
344 | customTheme.searchBubble.background = Jumio.Theme.Value(UIColor(hexString: searchBubbleBackground))
345 | }
346 |
347 | if let searchBubbleForeground = customizations["searchBubbleForeground"] as? [String: String?], let light = searchBubbleForeground["light"] as? String, let dark = searchBubbleForeground["dark"] as? String {
348 | customTheme.searchBubble.foreground = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
349 | } else if let searchBubbleForeground = customizations["searchBubbleForeground"] as? String {
350 | customTheme.searchBubble.foreground = Jumio.Theme.Value(UIColor(hexString: searchBubbleForeground))
351 | }
352 |
353 | if let searchBubbleOutline = customizations["searchBubbleOutline"] as? [String: String?], let light = searchBubbleOutline["light"] as? String, let dark = searchBubbleOutline["dark"] as? String {
354 | customTheme.searchBubble.outline = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
355 | } else if let searchBubbleOutline = customizations["searchBubbleOutline"] as? String {
356 | customTheme.searchBubble.outline = Jumio.Theme.Value(UIColor(hexString: searchBubbleOutline))
357 | }
358 |
359 | // Confirmation
360 | if let confirmationImageBackground = customizations["confirmationImageBackground"] as? [String: String?], let light = confirmationImageBackground["light"] as? String, let dark = confirmationImageBackground["dark"] as? String {
361 | customTheme.confirmation.imageBackground = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
362 | } else if let confirmationImageBackground = customizations["confirmationImageBackground"] as? String {
363 | customTheme.confirmation.imageBackground = Jumio.Theme.Value(UIColor(hexString: confirmationImageBackground))
364 | }
365 |
366 | if let confirmationImageBackgroundBorder = customizations["confirmationImageBackgroundBorder"] as? [String: String?], let light = confirmationImageBackgroundBorder["light"] as? String, let dark = confirmationImageBackgroundBorder["dark"] as? String {
367 | customTheme.confirmation.imageBackgroundBorder = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
368 | } else if let confirmationImageBackgroundBorder = customizations["confirmationImageBackgroundBorder"] as? String {
369 | customTheme.confirmation.imageBackgroundBorder = Jumio.Theme.Value(UIColor(hexString: confirmationImageBackgroundBorder))
370 | }
371 |
372 | if let confirmationIndicatorActive = customizations["confirmationIndicatorActive"] as? [String: String?], let light = confirmationIndicatorActive["light"] as? String, let dark = confirmationIndicatorActive["dark"] as? String {
373 | customTheme.confirmation.indicatorActive = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
374 | } else if let confirmationIndicatorActive = customizations["confirmationIndicatorActive"] as? String {
375 | customTheme.confirmation.indicatorActive = Jumio.Theme.Value(UIColor(hexString: confirmationIndicatorActive))
376 | }
377 |
378 | if let confirmationIndicatorDefault = customizations["confirmationIndicatorDefault"] as? [String: String?], let light = confirmationIndicatorDefault["light"] as? String, let dark = confirmationIndicatorDefault["dark"] as? String {
379 | customTheme.confirmation.indicatorDefault = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
380 | } else if let confirmationIndicatorDefault = customizations["confirmationIndicatorDefault"] as? String {
381 | customTheme.confirmation.indicatorDefault = Jumio.Theme.Value(UIColor(hexString: confirmationIndicatorDefault))
382 | }
383 |
384 | if let confirmationImageBorder = customizations["confirmationImageBorder"] as? [String: String?], let light = confirmationImageBorder["light"] as? String, let dark = confirmationImageBorder["dark"] as? String {
385 | customTheme.confirmation.imageBorder = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
386 | } else if let confirmationImageBorder = customizations["confirmationImageBorder"] as? String {
387 | customTheme.confirmation.imageBorder = Jumio.Theme.Value(UIColor(hexString: confirmationImageBorder))
388 | }
389 |
390 | // Global
391 | if let background = customizations["background"] as? [String: String?], let light = background["light"] as? String, let dark = background["dark"] as? String {
392 | customTheme.background = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
393 | } else if let background = customizations["background"] as? String {
394 | customTheme.background = Jumio.Theme.Value(UIColor(hexString: background))
395 | }
396 |
397 | if let navigationIconColor = customizations["navigationIconColor"] as? [String: String?], let light = navigationIconColor["light"] as? String, let dark = navigationIconColor["dark"] as? String {
398 | customTheme.navigationIconColor = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
399 | } else if let navigationIconColor = customizations["navigationIconColor"] as? String {
400 | customTheme.navigationIconColor = Jumio.Theme.Value(UIColor(hexString: navigationIconColor))
401 | }
402 |
403 | if let textForegroundColor = customizations["textForegroundColor"] as? [String: String?], let light = textForegroundColor["light"] as? String, let dark = textForegroundColor["dark"] as? String {
404 | customTheme.textForegroundColor = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
405 | } else if let textForegroundColor = customizations["textForegroundColor"] as? String {
406 | customTheme.textForegroundColor = Jumio.Theme.Value(UIColor(hexString: textForegroundColor))
407 | }
408 |
409 | if let primaryColor = customizations["primaryColor"] as? [String: String?], let light = primaryColor["light"] as? String, let dark = primaryColor["dark"] as? String {
410 | customTheme.primaryColor = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
411 | } else if let primaryColor = customizations["primaryColor"] as? String {
412 | customTheme.primaryColor = Jumio.Theme.Value(UIColor(hexString: primaryColor))
413 | }
414 |
415 | if let selectionIconForeground = customizations["selectionIconForeground"] as? [String: String?], let light = selectionIconForeground["light"] as? String, let dark = selectionIconForeground["dark"] as? String {
416 | customTheme.selectionIconForeground = Jumio.Theme.Value(light: UIColor(hexString: light), dark: UIColor(hexString: dark))
417 | } else if let selectionIconForeground = customizations["selectionIconForeground"] as? String {
418 | customTheme.selectionIconForeground = Jumio.Theme.Value(UIColor(hexString: selectionIconForeground))
419 | }
420 |
421 | return customTheme
422 | }
423 | }
424 |
--------------------------------------------------------------------------------
/ios/JumioMobileReactSdk.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/JumioMobileReactSdk.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/JumioMobileSDK.m:
--------------------------------------------------------------------------------
1 | //
2 | // JumioMobileSDK.m
3 | // JumioReactMobileSdk
4 | //
5 | // Copyright © 2021 Jumio Corporation All rights reserved.
6 | //
7 | #import
8 | #import
9 |
10 | @interface RCT_EXTERN_MODULE(JumioMobileSDK, RCTEventEmitter)
11 | RCT_EXTERN_METHOD(initialize:(NSString *)authorizationToken dataCenter:(NSString *)dataCenter)
12 | RCT_EXTERN_METHOD(setupCustomizations:(NSDictionary *)customizations)
13 | RCT_EXTERN_METHOD(start)
14 | RCT_EXTERN_METHOD(isRooted:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
15 | RCT_EXTERN_METHOD(setPreloaderFinishedBlock:(RCTResponseSenderBlock)completion)
16 | RCT_EXTERN_METHOD(preloadIfNeeded)
17 | @end
18 |
19 |
--------------------------------------------------------------------------------
/ios/JumioMobileSDK.swift:
--------------------------------------------------------------------------------
1 | //
2 | // JumioMobileSDK.swift
3 | // JumioReactMobileSdk
4 | //
5 | // Copyright © 2021 Jumio Corporation All rights reserved.
6 | //
7 |
8 | import Jumio
9 | import UIKit
10 |
11 | @objc(JumioMobileSDK)
12 | class JumioMobileSDK: RCTEventEmitter {
13 | fileprivate var jumio: Jumio.SDK?
14 | fileprivate var jumioVC: Jumio.ViewController?
15 | fileprivate var customizations: [String: Any?]?
16 | fileprivate var preloaderFinishedBlock: RCTResponseSenderBlock?
17 |
18 | override func supportedEvents() -> [String]! {
19 | return ["EventError", "EventResult"]
20 | }
21 |
22 | override static func requiresMainQueueSetup() -> Bool {
23 | return true
24 | }
25 |
26 | @objc func initialize(_ token: String, dataCenter: String) {
27 | jumio = Jumio.SDK()
28 | jumio?.defaultUIDelegate = self
29 | jumio?.token = token
30 | jumio?.setResourcesBundle(Bundle.main)
31 |
32 | switch dataCenter.lowercased() {
33 | case "eu":
34 | jumio?.dataCenter = .EU
35 | case "sg":
36 | jumio?.dataCenter = .SG
37 | default:
38 | jumio?.dataCenter = .US
39 | }
40 | }
41 |
42 | @objc func setupCustomizations(_ customizations: NSDictionary?) {
43 | if let customizations = customizations as? [String: Any?] {
44 | self.customizations = customizations
45 | }
46 | }
47 |
48 | @objc func start() {
49 | DispatchQueue.main.sync { [weak self] in
50 | guard let weakself = self, let jumio = jumio else { return }
51 |
52 | jumio.startDefaultUI()
53 |
54 | // Check if customization argument is added
55 | if let customizations = weakself.customizations {
56 | let customTheme = customizeSDKColors(customizations: customizations)
57 | jumio.customize(theme: customTheme)
58 | }
59 |
60 | weakself.jumioVC = try? jumio.viewController()
61 |
62 | guard let jumioVC = weakself.jumioVC else { return }
63 |
64 | jumioVC.modalPresentationStyle = .fullScreen
65 |
66 | guard let rootViewController = UIApplication.shared.windows.first?.rootViewController
67 | else { return }
68 |
69 | rootViewController.present(jumioVC, animated: true)
70 | }
71 | }
72 |
73 | @objc func isRooted(_ resolve: RCTPromiseResolveBlock, rejecter reject: RCTPromiseRejectBlock) {
74 | resolve(Jumio.SDK.isJailbroken)
75 | }
76 |
77 | @objc func setPreloaderFinishedBlock(_ completion: @escaping RCTResponseSenderBlock) {
78 | Jumio.Preloader.shared.delegate = self
79 | preloaderFinishedBlock = completion
80 | }
81 |
82 | @objc func preloadIfNeeded() {
83 | Jumio.Preloader.shared.preloadIfNeeded()
84 | }
85 |
86 | private func getIDResult(idResult: Jumio.IDResult) -> [String: Any] {
87 | let result: [String: Any?] = [
88 | "selectedCountry": idResult.country,
89 | "selectedDocumentType": idResult.idType,
90 | "selectedDocumentSubType":idResult.idSubType,
91 | "idNumber": idResult.documentNumber,
92 | "personalNumber": idResult.personalNumber,
93 | "issuingDate": idResult.issuingDate,
94 | "expiryDate": idResult.expiryDate,
95 | "issuingCountry": idResult.issuingCountry,
96 | "firstName": idResult.firstName,
97 | "lastName": idResult.lastName,
98 | "gender": idResult.gender,
99 | "nationality": idResult.nationality,
100 | "dateOfBirth": idResult.dateOfBirth,
101 | "addressLine": idResult.address,
102 | "city": idResult.city,
103 | "subdivision": idResult.subdivision,
104 | "postCode": idResult.postalCode,
105 | "placeOfBirth": idResult.placeOfBirth,
106 | "mrzLine1": idResult.mrzLine1,
107 | "mrzLine2": idResult.mrzLine2,
108 | "mrzLine3": idResult.mrzLine3,
109 | ]
110 |
111 | return result.compactMapValues { $0 }
112 | }
113 |
114 | private func getFaceResult(faceResult: Jumio.FaceResult) -> [String: Any] {
115 | let result: [String: Any?] = [
116 | "passed": (faceResult.passed ?? false) ? "true" : "false",
117 | ]
118 |
119 | return result.compactMapValues { $0 }
120 | }
121 | }
122 |
123 | extension JumioMobileSDK: Jumio.DefaultUIDelegate {
124 | func jumio(sdk: Jumio.SDK, finished result: Jumio.Result) {
125 | jumioVC?.dismiss(animated: true) { [weak self] in
126 | guard let weakself = self else { return }
127 |
128 | weakself.jumioVC = nil
129 | weakself.jumio = nil
130 | weakself.customizations = nil
131 |
132 | weakself.handleResult(jumioResult: result)
133 | }
134 | }
135 |
136 | private func handleResult(jumioResult: Jumio.Result) {
137 | let accountId = jumioResult.accountId
138 | let authenticationResult = jumioResult.isSuccess
139 | let credentialInfos = jumioResult.credentialInfos
140 | let workflowId = jumioResult.workflowExecutionId
141 |
142 | if authenticationResult == true {
143 | var body: [String: Any?] = [
144 | "accountId": accountId,
145 | "workflowId": workflowId,
146 | ]
147 | var credentialArray = [[String: Any?]]()
148 |
149 | credentialInfos.forEach { credentialInfo in
150 | var eventResultMap: [String: Any?] = [
151 | "credentialId": credentialInfo.id,
152 | "credentialCategory": "\(credentialInfo.category)",
153 | ]
154 |
155 | switch credentialInfo.category {
156 | case .id:
157 | if let idResult = jumioResult.getIDResult(of: credentialInfo) {
158 | eventResultMap = eventResultMap.merging(getIDResult(idResult: idResult), uniquingKeysWith: { first, _ in first })
159 | }
160 | case .face:
161 | if let faceResult = jumioResult.getFaceResult(of: credentialInfo) {
162 | eventResultMap = eventResultMap.merging(getFaceResult(faceResult: faceResult), uniquingKeysWith: { first, _ in first })
163 | }
164 | default:
165 | break
166 | }
167 |
168 | credentialArray.append(eventResultMap)
169 | }
170 | body["credentials"] = credentialArray
171 |
172 | sendEvent(withName: "EventResult", body: body)
173 | } else {
174 | guard let error = jumioResult.error else { return }
175 | let errorMessage = error.message
176 | let errorCode = error.code
177 |
178 | let body: [String: Any?] = [
179 | "errorCode": errorCode,
180 | "errorMessage": errorMessage,
181 | ]
182 |
183 | sendEvent(withName: "EventError", body: body)
184 | }
185 | }
186 | }
187 |
188 | extension JumioMobileSDK: Jumio.Preloader.Delegate {
189 | func jumio(finished: Jumio.Preloader) {
190 | preloaderFinishedBlock?([NSNull()])
191 | }
192 | }
193 |
--------------------------------------------------------------------------------
/ios/JumioReactMobileSdk-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
--------------------------------------------------------------------------------
/ios/JumioReactMobileSdk.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 768002C9274F9F24007E8DC5 /* JumioMobileSDKNetverify.swift in Sources */ = {isa = PBXBuildFile; fileRef = 768002C8274F9F24007E8DC5 /* JumioMobileSDKNetverify.swift */; };
11 | 768002CB274F9F9E007E8DC5 /* JumioMobileSDKNetverify.m in Sources */ = {isa = PBXBuildFile; fileRef = 768002CA274F9F9E007E8DC5 /* JumioMobileSDKNetverify.m */; };
12 | /* End PBXBuildFile section */
13 |
14 | /* Begin PBXCopyFilesBuildPhase section */
15 | 3438E4C224A38CA600360771 /* CopyFiles */ = {
16 | isa = PBXCopyFilesBuildPhase;
17 | buildActionMask = 2147483647;
18 | dstPath = "include/$(PRODUCT_NAME)";
19 | dstSubfolderSpec = 16;
20 | files = (
21 | );
22 | runOnlyForDeploymentPostprocessing = 0;
23 | };
24 | /* End PBXCopyFilesBuildPhase section */
25 |
26 | /* Begin PBXFileReference section */
27 | 3438E4C424A38CA600360771 /* libJumioReactMobileSdk.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libJumioReactMobileSdk.a; sourceTree = BUILT_PRODUCTS_DIR; };
28 | 768002C7274F9F24007E8DC5 /* JumioReactMobileSdk-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "JumioReactMobileSdk-Bridging-Header.h"; sourceTree = ""; };
29 | 768002C8274F9F24007E8DC5 /* JumioMobileSDKNetverify.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JumioMobileSDKNetverify.swift; sourceTree = ""; };
30 | 768002CA274F9F9E007E8DC5 /* JumioMobileSDKNetverify.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = JumioMobileSDKNetverify.m; sourceTree = ""; };
31 | /* End PBXFileReference section */
32 |
33 | /* Begin PBXFrameworksBuildPhase section */
34 | 3438E4C124A38CA600360771 /* Frameworks */ = {
35 | isa = PBXFrameworksBuildPhase;
36 | buildActionMask = 2147483647;
37 | files = (
38 | );
39 | runOnlyForDeploymentPostprocessing = 0;
40 | };
41 | /* End PBXFrameworksBuildPhase section */
42 |
43 | /* Begin PBXGroup section */
44 | 3438E4BB24A38CA600360771 = {
45 | isa = PBXGroup;
46 | children = (
47 | 768002C8274F9F24007E8DC5 /* JumioMobileSDKNetverify.swift */,
48 | 768002CA274F9F9E007E8DC5 /* JumioMobileSDKNetverify.m */,
49 | 3438E4C524A38CA600360771 /* Products */,
50 | 768002C7274F9F24007E8DC5 /* JumioReactMobileSdk-Bridging-Header.h */,
51 | );
52 | sourceTree = "";
53 | };
54 | 3438E4C524A38CA600360771 /* Products */ = {
55 | isa = PBXGroup;
56 | children = (
57 | 3438E4C424A38CA600360771 /* libJumioReactMobileSdk.a */,
58 | );
59 | name = Products;
60 | sourceTree = "";
61 | };
62 | /* End PBXGroup section */
63 |
64 | /* Begin PBXNativeTarget section */
65 | 3438E4C324A38CA600360771 /* JumioReactMobileSdk */ = {
66 | isa = PBXNativeTarget;
67 | buildConfigurationList = 3438E4CD24A38CA600360771 /* Build configuration list for PBXNativeTarget "JumioReactMobileSdk" */;
68 | buildPhases = (
69 | 3438E4C024A38CA600360771 /* Sources */,
70 | 3438E4C124A38CA600360771 /* Frameworks */,
71 | 3438E4C224A38CA600360771 /* CopyFiles */,
72 | );
73 | buildRules = (
74 | );
75 | dependencies = (
76 | );
77 | name = JumioReactMobileSdk;
78 | productName = JumioReactMobileSdk;
79 | productReference = 3438E4C424A38CA600360771 /* libJumioReactMobileSdk.a */;
80 | productType = "com.apple.product-type.library.static";
81 | };
82 | /* End PBXNativeTarget section */
83 |
84 | /* Begin PBXProject section */
85 | 3438E4BC24A38CA600360771 /* Project object */ = {
86 | isa = PBXProject;
87 | attributes = {
88 | LastUpgradeCheck = 1150;
89 | TargetAttributes = {
90 | 3438E4C324A38CA600360771 = {
91 | CreatedOnToolsVersion = 11.5;
92 | LastSwiftMigration = 1310;
93 | };
94 | };
95 | };
96 | buildConfigurationList = 3438E4BF24A38CA600360771 /* Build configuration list for PBXProject "JumioReactMobileSdk" */;
97 | compatibilityVersion = "Xcode 9.3";
98 | developmentRegion = en;
99 | hasScannedForEncodings = 0;
100 | knownRegions = (
101 | en,
102 | Base,
103 | );
104 | mainGroup = 3438E4BB24A38CA600360771;
105 | productRefGroup = 3438E4C524A38CA600360771 /* Products */;
106 | projectDirPath = "";
107 | projectRoot = "";
108 | targets = (
109 | 3438E4C324A38CA600360771 /* JumioReactMobileSdk */,
110 | );
111 | };
112 | /* End PBXProject section */
113 |
114 | /* Begin PBXSourcesBuildPhase section */
115 | 3438E4C024A38CA600360771 /* Sources */ = {
116 | isa = PBXSourcesBuildPhase;
117 | buildActionMask = 2147483647;
118 | files = (
119 | 768002C9274F9F24007E8DC5 /* JumioMobileSDKNetverify.swift in Sources */,
120 | 768002CB274F9F9E007E8DC5 /* JumioMobileSDKNetverify.m in Sources */,
121 | );
122 | runOnlyForDeploymentPostprocessing = 0;
123 | };
124 | /* End PBXSourcesBuildPhase section */
125 |
126 | /* Begin XCBuildConfiguration section */
127 | 3438E4CB24A38CA600360771 /* Debug */ = {
128 | isa = XCBuildConfiguration;
129 | buildSettings = {
130 | ALWAYS_SEARCH_USER_PATHS = NO;
131 | CLANG_ANALYZER_NONNULL = YES;
132 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
133 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
134 | CLANG_CXX_LIBRARY = "libc++";
135 | CLANG_ENABLE_MODULES = YES;
136 | CLANG_ENABLE_OBJC_ARC = YES;
137 | CLANG_ENABLE_OBJC_WEAK = YES;
138 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
139 | CLANG_WARN_BOOL_CONVERSION = YES;
140 | CLANG_WARN_COMMA = YES;
141 | CLANG_WARN_CONSTANT_CONVERSION = YES;
142 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
143 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
144 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
145 | CLANG_WARN_EMPTY_BODY = YES;
146 | CLANG_WARN_ENUM_CONVERSION = YES;
147 | CLANG_WARN_INFINITE_RECURSION = YES;
148 | CLANG_WARN_INT_CONVERSION = YES;
149 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
150 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
151 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
152 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
153 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
154 | CLANG_WARN_STRICT_PROTOTYPES = YES;
155 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
156 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
157 | CLANG_WARN_UNREACHABLE_CODE = YES;
158 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
159 | COPY_PHASE_STRIP = NO;
160 | DEBUG_INFORMATION_FORMAT = dwarf;
161 | ENABLE_STRICT_OBJC_MSGSEND = YES;
162 | ENABLE_TESTABILITY = YES;
163 | GCC_C_LANGUAGE_STANDARD = gnu11;
164 | GCC_DYNAMIC_NO_PIC = NO;
165 | GCC_NO_COMMON_BLOCKS = YES;
166 | GCC_OPTIMIZATION_LEVEL = 0;
167 | GCC_PREPROCESSOR_DEFINITIONS = (
168 | "DEBUG=1",
169 | "$(inherited)",
170 | );
171 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
172 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
173 | GCC_WARN_UNDECLARED_SELECTOR = YES;
174 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
175 | GCC_WARN_UNUSED_FUNCTION = YES;
176 | GCC_WARN_UNUSED_VARIABLE = YES;
177 | IPHONEOS_DEPLOYMENT_TARGET = 10.0;
178 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
179 | MTL_FAST_MATH = YES;
180 | ONLY_ACTIVE_ARCH = YES;
181 | SDKROOT = iphoneos;
182 | };
183 | name = Debug;
184 | };
185 | 3438E4CC24A38CA600360771 /* Release */ = {
186 | isa = XCBuildConfiguration;
187 | buildSettings = {
188 | ALWAYS_SEARCH_USER_PATHS = NO;
189 | CLANG_ANALYZER_NONNULL = YES;
190 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
191 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
192 | CLANG_CXX_LIBRARY = "libc++";
193 | CLANG_ENABLE_MODULES = YES;
194 | CLANG_ENABLE_OBJC_ARC = YES;
195 | CLANG_ENABLE_OBJC_WEAK = YES;
196 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
197 | CLANG_WARN_BOOL_CONVERSION = YES;
198 | CLANG_WARN_COMMA = YES;
199 | CLANG_WARN_CONSTANT_CONVERSION = YES;
200 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
201 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
202 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
203 | CLANG_WARN_EMPTY_BODY = YES;
204 | CLANG_WARN_ENUM_CONVERSION = YES;
205 | CLANG_WARN_INFINITE_RECURSION = YES;
206 | CLANG_WARN_INT_CONVERSION = YES;
207 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
208 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
209 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
210 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
211 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
212 | CLANG_WARN_STRICT_PROTOTYPES = YES;
213 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
214 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
215 | CLANG_WARN_UNREACHABLE_CODE = YES;
216 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
217 | COPY_PHASE_STRIP = NO;
218 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
219 | ENABLE_NS_ASSERTIONS = NO;
220 | ENABLE_STRICT_OBJC_MSGSEND = YES;
221 | GCC_C_LANGUAGE_STANDARD = gnu11;
222 | GCC_NO_COMMON_BLOCKS = YES;
223 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
224 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
225 | GCC_WARN_UNDECLARED_SELECTOR = YES;
226 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
227 | GCC_WARN_UNUSED_FUNCTION = YES;
228 | GCC_WARN_UNUSED_VARIABLE = YES;
229 | IPHONEOS_DEPLOYMENT_TARGET = 10.0;
230 | MTL_ENABLE_DEBUG_INFO = NO;
231 | MTL_FAST_MATH = YES;
232 | SDKROOT = iphoneos;
233 | VALIDATE_PRODUCT = YES;
234 | };
235 | name = Release;
236 | };
237 | 3438E4CE24A38CA600360771 /* Debug */ = {
238 | isa = XCBuildConfiguration;
239 | buildSettings = {
240 | CLANG_ENABLE_MODULES = YES;
241 | CODE_SIGN_STYLE = Automatic;
242 | LD_RUNPATH_SEARCH_PATHS = (
243 | "$(inherited)",
244 | "@executable_path/Frameworks",
245 | "@loader_path/Frameworks",
246 | );
247 | OTHER_LDFLAGS = "-ObjC";
248 | PRODUCT_NAME = "$(TARGET_NAME)";
249 | SKIP_INSTALL = YES;
250 | SWIFT_OBJC_BRIDGING_HEADER = "JumioReactMobileSdk-Bridging-Header.h";
251 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
252 | SWIFT_VERSION = 5.0;
253 | TARGETED_DEVICE_FAMILY = "1,2";
254 | };
255 | name = Debug;
256 | };
257 | 3438E4CF24A38CA600360771 /* Release */ = {
258 | isa = XCBuildConfiguration;
259 | buildSettings = {
260 | CLANG_ENABLE_MODULES = YES;
261 | CODE_SIGN_STYLE = Automatic;
262 | LD_RUNPATH_SEARCH_PATHS = (
263 | "$(inherited)",
264 | "@executable_path/Frameworks",
265 | "@loader_path/Frameworks",
266 | );
267 | OTHER_LDFLAGS = "-ObjC";
268 | PRODUCT_NAME = "$(TARGET_NAME)";
269 | SKIP_INSTALL = YES;
270 | SWIFT_OBJC_BRIDGING_HEADER = "JumioReactMobileSdk-Bridging-Header.h";
271 | SWIFT_VERSION = 5.0;
272 | TARGETED_DEVICE_FAMILY = "1,2";
273 | };
274 | name = Release;
275 | };
276 | /* End XCBuildConfiguration section */
277 |
278 | /* Begin XCConfigurationList section */
279 | 3438E4BF24A38CA600360771 /* Build configuration list for PBXProject "JumioReactMobileSdk" */ = {
280 | isa = XCConfigurationList;
281 | buildConfigurations = (
282 | 3438E4CB24A38CA600360771 /* Debug */,
283 | 3438E4CC24A38CA600360771 /* Release */,
284 | );
285 | defaultConfigurationIsVisible = 0;
286 | defaultConfigurationName = Release;
287 | };
288 | 3438E4CD24A38CA600360771 /* Build configuration list for PBXNativeTarget "JumioReactMobileSdk" */ = {
289 | isa = XCConfigurationList;
290 | buildConfigurations = (
291 | 3438E4CE24A38CA600360771 /* Debug */,
292 | 3438E4CF24A38CA600360771 /* Release */,
293 | );
294 | defaultConfigurationIsVisible = 0;
295 | defaultConfigurationName = Release;
296 | };
297 | /* End XCConfigurationList section */
298 | };
299 | rootObject = 3438E4BC24A38CA600360771 /* Project object */;
300 | }
301 |
--------------------------------------------------------------------------------
/ios/JumioReactMobileSdk.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ios/JumioReactMobileSdk.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/ios/UIColorExtension.swift:
--------------------------------------------------------------------------------
1 | extension UIColor {
2 | convenience init(hexString: String) {
3 | let hex = hexString.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
4 | var int = UInt64()
5 | Scanner(string: hex).scanHexInt64(&int)
6 | let a, r, g, b: UInt64
7 | switch hex.count {
8 | case 3: // RGB (12-bit)
9 | (a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
10 | case 6: // RGB (24-bit)
11 | (a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF)
12 | case 8: // ARGB (32-bit)
13 | (a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
14 | default:
15 | (a, r, g, b) = (255, 0, 0, 0)
16 | }
17 | self.init(red: CGFloat(r) / 255, green: CGFloat(g) / 255, blue: CGFloat(b) / 255, alpha: CGFloat(a) / 255)
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/ios/react-native-jumio-mobilesdk-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import
2 | #import
3 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-jumio-mobilesdk",
3 | "version": "4.13.0",
4 | "lockfileVersion": 1
5 | }
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-native-jumio-mobilesdk",
3 | "version": "4.13.0",
4 | "description": "Official Jumio Mobile SDK plugin for React Native",
5 | "repository": {
6 | "type": "git",
7 | "url": "https://github.com/Jumio/mobile-react"
8 | },
9 | "license": "SEE LICENSE IN README.md",
10 | "keywords": [
11 | "react-native",
12 | "react-ios",
13 | "react-android"
14 | ],
15 | "scripts": {
16 | "start": "node node_modules/react-native/local-cli/cli.js start",
17 | "test": "jest"
18 | },
19 | "peerDependencies": {
20 | "react-native": ">=0.47.1"
21 | },
22 | "author": "Jumio Corporation"
23 | }
--------------------------------------------------------------------------------
/react-native-jumio-mobilesdk.podspec:
--------------------------------------------------------------------------------
1 | require "json"
2 |
3 | package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4 |
5 | Pod::Spec.new do |s|
6 | s.name = package["name"]
7 | s.version = package["version"]
8 | s.summary = package["description"]
9 | s.description = <<-DESC
10 | react-native-jumio-mobilesdk
11 | DESC
12 | s.homepage = "https://github.com/Jumio/mobile-react"
13 | s.license = package["license"]
14 | s.authors = { "Jumio Corporation" => "support@jumio.com" }
15 | s.platforms = { :ios => "13.0" }
16 | s.source = { :git => "https://github.com/Jumio/mobile-react.git", :tag => "#{s.version}" }
17 |
18 | s.source_files = "ios/**/*.{h,c,m,swift}"
19 | s.requires_arc = true
20 |
21 | s.pod_target_xcconfig = {
22 | 'OTHER_SWIFT_FLAGS' => '-no-verify-emitted-module-interface',
23 | }
24 |
25 | s.dependency "React-Core"
26 | s.dependency "Jumio", "~> 4.13.0"
27 | end
28 |
--------------------------------------------------------------------------------