Skip to content

Commit 66e7731

Browse files
added 11.8.2
1 parent df4de3b commit 66e7731

File tree

7 files changed

+148
-57
lines changed

7 files changed

+148
-57
lines changed

README.md

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
# Acuant JavaScript Web SDK v11.8.1
1+
# Acuant JavaScript Web SDK v11.8.2
22

3-
**March 2023**
3+
**April 2023**
44

55
See [https://github.com/Acuant/JavascriptWebSDKV11/releases](https://github.com/Acuant/JavascriptWebSDKV11/releases) for release notes.
66

@@ -728,6 +728,12 @@ Web Workers/WASM and CDNs can be used together with workarounds. The following c
728728

729729
----------
730730

731+
## Using the SDK as part of an iOS or Android WebView
732+
733+
See the [WebView ReadMe](docs/WebViewReadMe.md) for documentation on WebViews.
734+
735+
----------
736+
731737
## Improved support for devices with extreme memory constraints.
732738

733739
Although the Web Workers use only a minimal amount of memory, you can reduce the memory usage by running only one of the Web Workers at a time. This is recommended only if you have severe memory constraints that you can not address any other way. Normally when both **AcauntImageWorker** and **AcuantMetricsWorker** are running simultaneously, they seamlessly make calls between themselves until they are ready to return a finished image that has been cropped and has had all the metrics run on it. If only one is running at a time, the workflow has to look like this:
@@ -743,9 +749,9 @@ Starting and stopping Workers is a very slow operation, so you will see performa
743749

744750
## Known Issues/FAQ
745751

746-
1. iPhone 13 Pro, 13 Pro Max, 14 Pro, and 14 Pro Max struggle to focus at close distances when running iOS 16.
752+
1. iPhone 13 Pro, 13 Pro Max, 14 Pro, and 14 Pro Max struggle to focus at close distances when running iOS 16.0 through 16.3.
747753

748-
11.7.1 adds a workaround for this issue by having those devices capture from further away. This is a workaround for an issue in iOS 16. There is a more detailed explanation of both the issue and the workaround in the 11.7.1 section of the [Migration Details](docs/MigrationDetails.md). We have been in contact with Apple and they tell us that they are now aware of the issue and are looking into it.
754+
11.7.1 adds a workaround for this issue by having those devices capture from farther away. This is a workaround for an issue in iOS 16. There is a more detailed explanation of both the issue and the workaround in the 11.7.1 section of the [Migration Details](docs/MigrationDetails.md). We have been in contact with Apple and as of iOS 16.4 Apple has provided us with the tools to fix this issue properly. This fix was released as part of 11.8.2.
749755

750756
1. iOS 15 has multiple issues that manifest themselves as GPU Highwater failures (ie system daemon used too much memory).
751757

app/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ <h3 id="acuant-modal-text"></h3>
304304

305305
function startCamera() {
306306
currentResult = {};
307-
if (AcuantCamera.isCameraSupported && !AcuantCamera.isIOSWebview && !liveCaptureFailed) {
307+
if (AcuantCamera.isCameraSupported && !liveCaptureFailed) {
308308
cameraBtn.style.display = "none";
309309
camera.style.display = "block";
310310

docs/WebViewReadMe.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Web View Implementation Information
2+
3+
## Android
4+
5+
1. The app that contains the WebView must first declare and obtain the following permissions:
6+
7+
<uses-permission android:name="android.permission.INTERNET"/>
8+
<uses-permission android:name="android.permission.CAMERA" />
9+
10+
1. Override the following methods within 'webChromeClient' property of your WebView, using either an inline object or a custom class.
11+
12+
13+
* This function is used to grant the relevant permissions to the webpage:
14+
15+
16+
override fun onPermissionRequest(request: PermissionRequest) {
17+
request.grant(request.resources)
18+
}
19+
20+
* The following function implements the file selection dialog for the manual capture fallback (if the user does not grant or unexpectedly revokes the camera permission):
21+
22+
override fun onShowFileChooser(
23+
webView: WebView?,
24+
filePathCallback: ValueCallback<Array<Uri>>?,
25+
fileChooserParams: FileChooserParams?
26+
): Boolean {
27+
//save the callback to be accessible to the on activity result function.
28+
this@MainActivity.filePathCallback = filePathCallback
29+
30+
//create the file selection dialog intent from the params set by the webpage.
31+
val intent = fileChooserParams!!.createIntent()
32+
try {
33+
//launch activity for result.
34+
resultLauncher.launch(intent)
35+
} catch (e: ActivityNotFoundException) {
36+
//this exception is highly unlikely, but should be handled nonetheless. Since the file selection dialog is already the fallback to the main capture experience, assume the user is unable to proceed via the app.
37+
return false
38+
}
39+
return true
40+
}
41+
42+
* Then add the following at the activity level:
43+
44+
//the callback being saved to be accessible in the activity.
45+
private var filePathCallback: ValueCallback<Array<Uri>>? = null
46+
47+
//the modern format of start activity for result.
48+
private val resultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
49+
val data: Intent? = result.data
50+
51+
//pass the data to the WebView.
52+
filePathCallback?.onReceiveValue(
53+
WebChromeClient.FileChooserParams.parseResult(result.resultCode, data)
54+
)
55+
}
56+
57+
1. For the WebView settings, set the following properties:
58+
59+
wvSettings.javaScriptEnabled = true
60+
wvSettings.domStorageEnabled = true
61+
wvSettings.allowFileAccess = true
62+
wvSettings.allowContentAccess = true
63+
wvSettings.javaScriptCanOpenWindowsAutomatically = true
64+
wvSettings.mediaPlaybackRequiresUserGesture = false
65+
66+
## iOS
67+
68+
1. Declare a camera permission message by adding NSCameraUsageDescription to the info.plist.
69+
70+
1. iOS requires the following WebView definition:
71+
72+
//Create Web View
73+
let webConfiguration = WKWebViewConfiguration()
74+
webConfiguration.allowsInlineMediaPlayback = true
75+
WKWebView(frame: CGRect(x: 0, y: 0, width: 200, height: 200), configuration: webConfiguration)
76+
77+
//Load Web View
78+
let request = URLRequest(url: "yourWebUrl")
79+
webView.load(request)

webSdk/AcuantCamera.js

Lines changed: 55 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -686,32 +686,35 @@ var AcuantCamera = (function () {
686686
//could be prone to error
687687
function getDevice() {
688688
return new Promise((resolve) => {
689-
navigator.mediaDevices.enumerateDevices().then(function(devices) {
690-
const minSuffixDevice = {
691-
suffix: undefined,
692-
device: undefined,
693-
};
694-
devices.filter((device) => {
695-
return device.kind === 'videoinput';
696-
})
697-
.forEach(function(device) {
698-
const activeCameraIsBackFacing = (device.getCapabilities && device.getCapabilities().facingMode.length && device.getCapabilities().facingMode[0] === 'environment')
699-
|| isBackCameraLabel(device.label);
700-
if (activeCameraIsBackFacing) {
701-
let split = device.label.split(',');
702-
let cameraSuffixNumber = parseInt(split[0][split[0].length -1]);
703-
704-
if (cameraSuffixNumber || cameraSuffixNumber === 0) {
705-
if (minSuffixDevice.suffix === undefined || minSuffixDevice.suffix > cameraSuffixNumber) {
706-
minSuffixDevice.suffix = cameraSuffixNumber;
707-
minSuffixDevice.device = device;
689+
navigator.mediaDevices.enumerateDevices()
690+
.then((devices) => {
691+
const minSuffixDevice = {
692+
suffix: undefined,
693+
device: undefined,
694+
};
695+
const dualWideCamera = devices.find(d => d.label === 'Back Dual Wide Camera');
696+
if (isiOS164Plus() && dualWideCamera) {
697+
minSuffixDevice.device = dualWideCamera;
698+
} else {
699+
devices
700+
.filter(device => device.kind === 'videoinput')
701+
.forEach(device => {
702+
if (isBackCameraLabel(device.label)) {
703+
let split = device.label.split(',');
704+
let cameraSuffixNumber = parseInt(split[0][split[0].length -1]);
705+
706+
if (cameraSuffixNumber || cameraSuffixNumber === 0) {
707+
if (minSuffixDevice.suffix === undefined || minSuffixDevice.suffix > cameraSuffixNumber) {
708+
minSuffixDevice.suffix = cameraSuffixNumber;
709+
minSuffixDevice.device = device;
710+
}
711+
}
708712
}
709-
}
710-
}
711-
});
712-
resolve(minSuffixDevice.device);
713-
})
714-
.catch(function() {
713+
});
714+
}
715+
resolve(minSuffixDevice.device);
716+
})
717+
.catch(() => {
715718
resolve();
716719
});
717720
});
@@ -720,23 +723,24 @@ var AcuantCamera = (function () {
720723
function startCamera(constraints, iteration = 0) {
721724
const MAX_ITERATIONS = 2;
722725

723-
const getDeviceWasAbleToReadLabels = Boolean(constraints.video.deviceId);
724-
navigator.mediaDevices.getUserMedia(constraints).then((stream) => {
725-
if (!getDeviceWasAbleToReadLabels && iteration < MAX_ITERATIONS) {
726-
// Check if there is a better camera to use once we have permissions
727-
getDevice().then(function(device) {
728-
if (device && device.deviceId !== stream.getVideoTracks()[0].getSettings().deviceId) {
729-
userConfig.primaryConstraints.video.deviceId = device.deviceId;
730-
stopMediaTracks(stream);
731-
startCamera(userConfig.primaryConstraints, iteration++);
732-
} else {
733-
enableCamera(stream);
734-
}
735-
});
736-
} else {
737-
enableCamera(stream);
738-
}
739-
})
726+
const getDeviceWasAbleToReadLabels = Boolean(constraints);
727+
navigator.mediaDevices.getUserMedia(constraints)
728+
.then((stream) => {
729+
if (!getDeviceWasAbleToReadLabels && iteration < MAX_ITERATIONS) {
730+
// Check if there is a better camera to use once we have permissions
731+
getDevice().then((device) => {
732+
if (device && device.deviceId !== stream.getVideoTracks()[0].getSettings().deviceId) {
733+
userConfig.primaryConstraints.video.deviceId = device.deviceId;
734+
stopMediaTracks(stream);
735+
startCamera(userConfig.primaryConstraints, iteration++);
736+
} else {
737+
enableCamera(stream);
738+
}
739+
});
740+
} else {
741+
enableCamera(stream);
742+
}
743+
})
740744
.catch((error) => {
741745
callCameraError(error, AcuantJavascriptWebSdk.START_FAIL_CODE);
742746
});
@@ -790,10 +794,7 @@ var AcuantCamera = (function () {
790794
}
791795

792796
acuantCamera.dispatchEvent(new Event('acuantcameracreated'));
793-
getDevice().then((device) => {
794-
if (device) userConfig.primaryConstraints.video.deviceId = device.deviceId;
795-
startCamera(userConfig.primaryConstraints);
796-
});
797+
startCamera(userConfig.primaryConstraints);
797798
}
798799
}
799800

@@ -990,9 +991,14 @@ var AcuantCamera = (function () {
990991
return ver && ver != -1 && ver.length >= 1 && ver[0] == 15;
991992
}
992993

993-
function isiOS16() {
994+
function isiOS163OrLess() {
995+
let ver = iOSversion();
996+
return ver && ver != -1 && ver.length >= 1 && ver[0] == 16 && ver [1] < 4;
997+
}
998+
999+
function isiOS164Plus() {
9941000
let ver = iOSversion();
995-
return ver && ver != -1 && ver.length >= 1 && ver[0] == 16;
1001+
return ver && ver != -1 && ver.length >= 1 && ver[0] >= 16 && ver [1] >= 4;
9961002
}
9971003

9981004
function isDeviceAffectedByIOS16Issue() {
@@ -1003,7 +1009,7 @@ var AcuantCamera = (function () {
10031009
if (decodedCookie.includes('AcuantForceDistantCapture=true')) {
10041010
return true;
10051011
}
1006-
if (isiOS16()) {
1012+
if (isiOS163OrLess()) {
10071013
let dims = [screen.width, screen.height];
10081014
let long = Math.max(...dims);
10091015
let short = Math.min(...dims);

webSdk/AcuantCamera.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webSdk/AcuantJavascriptWebSdk.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webSdk/AcuantPassiveLiveness.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)