Skip to content

Commit

Permalink
Merge pull request #11 from blinkcard/release/2.10.0
Browse files Browse the repository at this point in the history
Release/2.10.0
  • Loading branch information
mparadina authored Oct 24, 2024
2 parents 88af5e3 + 84c0256 commit da0e04e
Show file tree
Hide file tree
Showing 15 changed files with 402 additions and 229 deletions.
2 changes: 1 addition & 1 deletion BlinkCard/blinkcard-react-native.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ Pod::Spec.new do |s|
s.source = { :git => "https://github.com/BlinkCard/blinkcard-react-native.git", :tag => "v#{s.version}" }
s.source_files = "src/ios", "src/ios/**/*.{h,m}"
s.dependency 'React'
s.dependency 'MBBlinkCard', '~> 2.9.1'
s.dependency 'MBBlinkCard', '~> 2.10.0'
s.frameworks = 'UIKit'
end
2 changes: 1 addition & 1 deletion BlinkCard/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ export class RecognizerCollection {
*/
this.allowMultipleResults = false;
/** Number of miliseconds after first non-empty result becomes available to end scanning with a timeout */
this.milisecondsBeforeTimeout = 10000;
this.milisecondsBeforeTimeout = 0;

if (!(this.recognizerArray instanceof Array)) {
throw new Error("recognizerArray must be array of Recognizer objects!");
Expand Down
25 changes: 24 additions & 1 deletion BlinkCard/overlays/blinkCardOverlays.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { OverlaySettings } from '../overlaySettings'

import { AndroidCameraResolutionPreset,
iOSCameraResolutionPreset
} from '../types'
/**
* Class for setting up BlinkCard overlay.
* BlinkCard overlay is best suited for scanning payment cards.
Expand Down Expand Up @@ -73,5 +75,26 @@ export class BlinkCardOverlaySettings extends OverlaySettings {
* example: "US" to use "en_US" on Android and en-US on iOS
*/
this.country = null;

/**
* Defines possible iOS device camera video resolution preset.
*
* Default: PresetOptimal
*/
this.iOSCameraResolutionPreset = iOSCameraResolutionPreset.PresetOptimal;

/**
* Defines possible Android device camera video resolution preset.
*
* Default: PresetDefault
*/
this.androidCameraResolutionPreset = AndroidCameraResolutionPreset.PresetDefault;

/**
* Option to set whether legacy camera API should be used even on Lollipop devices that support newer Camera2 API.
*
* Default: false
*/
this.enableAndroidLegacyCameraApi = false;
}
}
2 changes: 1 addition & 1 deletion BlinkCard/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion BlinkCard/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@microblink/blinkcard-react-native",
"version": "2.9.1",
"version": "2.10.0",
"description": "AI-driven credit card scanning for cross-platform apps built with ReactNative.",
"main": "index.js",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion BlinkCard/src/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ android {

dependencies {
implementation 'com.facebook.react:react-native:+'
implementation('com.microblink:blinkcard:2.9.3@aar') {
implementation('com.microblink:blinkcard:2.10.0@aar') {
transitive = true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import com.microblink.blinkcard.metadata.recognition.FirstSideRecognitionCallback;
import com.microblink.blinkcard.recognition.RecognitionSuccessType;
import com.microblink.blinkcard.view.recognition.ScanResultListener;
import com.microblink.blinkcard.licence.exception.LicenceKeyException;

import com.microblink.blinkcard.uisettings.UISettings;
import com.microblink.blinkcard.reactnative.recognizers.RecognizerSerializers;
Expand Down Expand Up @@ -75,93 +76,94 @@ public String getName() {

@ReactMethod
public void scanWithCamera(ReadableMap jsonOverlaySettings, ReadableMap jsonRecognizerCollection, ReadableMap license, Promise promise) {
prepareScanning(license, promise);
try {
LanguageUtils.setLanguageAndCountry(jsonOverlaySettings.getString("language"),
jsonOverlaySettings.getString("country"),
getCurrentActivity());
} catch (Exception e) {}
mRecognizerBundle = RecognizerSerializers.INSTANCE.deserializeRecognizerCollection(jsonRecognizerCollection);
UISettings overlaySettings = OverlaySettingsSerializers.INSTANCE.getOverlaySettings(getReactApplicationContext(), jsonOverlaySettings, mRecognizerBundle);
ActivityRunner.startActivityForResult(getCurrentActivity(), REQUEST_CODE, overlaySettings);
if(prepareScanning(license, promise)) {
try {
LanguageUtils.setLanguageAndCountry(jsonOverlaySettings.getString("language"),
jsonOverlaySettings.getString("country"),
getCurrentActivity());
} catch (Exception e) {}
mRecognizerBundle = RecognizerSerializers.INSTANCE.deserializeRecognizerCollection(jsonRecognizerCollection);
UISettings overlaySettings = OverlaySettingsSerializers.INSTANCE.getOverlaySettings(getReactApplicationContext(), jsonOverlaySettings, mRecognizerBundle);
ActivityRunner.startActivityForResult(getCurrentActivity(), REQUEST_CODE, overlaySettings);
}
}

@ReactMethod
private void scanWithDirectApi(ReadableMap jsonRecognizerCollection, ReadableMap frontImage, ReadableMap backImage, ReadableMap license, Promise promise) {
//DirectAPI processing
mScanPromise = promise;
prepareScanning(license, promise);

ScanResultListener mScanResultListenerBackSide = new ScanResultListener() {
@Override
public void onScanningDone(@NonNull RecognitionSuccessType recognitionSuccessType) {
mFirstSideScanned = false;
handleDirectApiResult(recognitionSuccessType);
}
@Override
public void onUnrecoverableError(@NonNull Throwable throwable) {
promise.reject(throwable);
}
};
if(prepareScanning(license, promise)) {
ScanResultListener mScanResultListenerBackSide = new ScanResultListener() {
@Override
public void onScanningDone(@NonNull RecognitionSuccessType recognitionSuccessType) {
mFirstSideScanned = false;
handleDirectApiResult(recognitionSuccessType);
}
@Override
public void onUnrecoverableError(@NonNull Throwable throwable) {
promise.reject(throwable);
}
};

FirstSideRecognitionCallback mFirstSideRecognitionCallback = new FirstSideRecognitionCallback() {
@Override
public void onFirstSideRecognitionFinished() {
mFirstSideScanned = true;
}
};
FirstSideRecognitionCallback mFirstSideRecognitionCallback = new FirstSideRecognitionCallback() {
@Override
public void onFirstSideRecognitionFinished() {
mFirstSideScanned = true;
}
};

ScanResultListener mScanResultListenerFrontSide = new ScanResultListener() {
@Override
public void onScanningDone(@NonNull RecognitionSuccessType recognitionSuccessType) {
if (mFirstSideScanned == true) {
//multiside recognizer used
try {
if (backImage != null) {
processImage(backImage.getString(PARAM_BACK_IMAGE), mScanResultListenerBackSide);
} else if (recognitionSuccessType != RecognitionSuccessType.UNSUCCESSFUL) {
handleDirectApiResult(recognitionSuccessType);
} else {
handleDirectApiError("Could not extract the information from the front side and back side is empty!", promise);
ScanResultListener mScanResultListenerFrontSide = new ScanResultListener() {
@Override
public void onScanningDone(@NonNull RecognitionSuccessType recognitionSuccessType) {
if (mFirstSideScanned == true) {
//multiside recognizer used
try {
if (backImage != null) {
processImage(backImage.getString(PARAM_BACK_IMAGE), mScanResultListenerBackSide);
} else if (recognitionSuccessType != RecognitionSuccessType.UNSUCCESSFUL) {
handleDirectApiResult(recognitionSuccessType);
} else {
handleDirectApiError("Could not extract the information from the front side and back side is empty!", promise);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
} catch (Exception e) {
throw new RuntimeException(e);
} else if (mFirstSideScanned == false && recognitionSuccessType != RecognitionSuccessType.UNSUCCESSFUL){
//singleside recognizer used
handleDirectApiResult(recognitionSuccessType);
} else {
mFirstSideScanned = false;
handleDirectApiError("Could not extract the information with DirectAPI!", promise);
}
} else if (mFirstSideScanned == false && recognitionSuccessType != RecognitionSuccessType.UNSUCCESSFUL){
//singleside recognizer used
handleDirectApiResult(recognitionSuccessType);
} else {
mFirstSideScanned = false;
handleDirectApiError("Could not extract the information with DirectAPI!", promise);
}
}
@Override
public void onUnrecoverableError(@NonNull Throwable throwable) {
promise.reject(throwable);
}
};
@Override
public void onUnrecoverableError(@NonNull Throwable throwable) {
promise.reject(throwable);
}
};

setupRecognizerRunner(jsonRecognizerCollection, mFirstSideRecognitionCallback, promise);
setupRecognizerRunner(jsonRecognizerCollection, mFirstSideRecognitionCallback, promise);

if (frontImage != null) {
processImage(frontImage.getString(PARAM_FRONT_IMAGE), mScanResultListenerFrontSide);
} else {
handleDirectApiError("The provided image for the 'frontImage' parameter is empty!", promise);
if (frontImage != null) {
processImage(frontImage.getString(PARAM_FRONT_IMAGE), mScanResultListenerFrontSide);
} else {
handleDirectApiError("The provided image for the 'frontImage' parameter is empty!", promise);
}
}
}

private void prepareScanning(ReadableMap license, Promise promise) {
private boolean prepareScanning(ReadableMap license, Promise promise) {
Activity currentActivity = getCurrentActivity();
if (currentActivity == null) {
promise.reject(ERROR_ACTIVITY_DOES_NOT_EXIST, "Activity does not exist");
return;
return false;
}

// Store the promise to resolve/reject when scanning is done
mScanPromise = promise;
if (!license.hasKey(PARAM_LICENSE_KEY)) {
promise.reject(ERROR_LICENSE_KEY_NOT_SET, "License key is not set");
return;
return false;
}
String licenseKey = license.getString(PARAM_LICENSE_KEY);
String licensee = null;
Expand All @@ -172,7 +174,8 @@ private void prepareScanning(ReadableMap license, Promise promise) {
if (license.hasKey(PARAM_SHOW_TRIAL_LICENSE_WARNING)) {
showTrialLicenseKeyWarning = license.getBoolean(PARAM_SHOW_TRIAL_LICENSE_WARNING);
}
setLicense(licenseKey, licensee, showTrialLicenseKeyWarning);

return setLicense(licenseKey, licensee, showTrialLicenseKeyWarning);
}

private void setupRecognizerRunner(ReadableMap jsonRecognizerCollection, FirstSideRecognitionCallback mFirstSideRecognitionCallback, Promise promise) {
Expand Down Expand Up @@ -233,16 +236,27 @@ private Bitmap base64ToBitmap(String base64String) {
return BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.length);
}

private void setLicense( String licenseKey, String licensee, Boolean showTrialLicenseKeyWarning ) {
private boolean setLicense( String licenseKey, String licensee, Boolean showTrialLicenseKeyWarning ) {
if (showTrialLicenseKeyWarning != null) {
MicroblinkSDK.setShowTrialLicenseWarning(showTrialLicenseKeyWarning);
}
if (licensee != null) {
MicroblinkSDK.setLicenseKey(licenseKey, licensee, this.getCurrentActivity());
try {
MicroblinkSDK.setLicenseKey(licenseKey, licensee, this.getCurrentActivity());
} catch (LicenceKeyException licenceKeyException) {
mScanPromise.reject("Android license key error: " + licenceKeyException.toString());
return false;
}
} else {
MicroblinkSDK.setLicenseKey(licenseKey, this.getCurrentActivity());
try {
MicroblinkSDK.setLicenseKey(licenseKey, this.getCurrentActivity());
} catch (LicenceKeyException licenceKeyException) {
mScanPromise.reject("Android license key error: " + licenceKeyException.toString());
return false;
}
}
MicroblinkSDK.setIntentDataTransferMode(IntentDataTransferMode.PERSISTED_OPTIMISED);
return true;
}

private void rejectPromise(String code, String message) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import com.microblink.blinkcard.reactnative.overlays.OverlaySettingsSerialization;
import com.microblink.blinkcard.uisettings.BlinkCardUISettings;
import com.microblink.blinkcard.uisettings.UISettings;
import com.microblink.blinkcard.hardware.camera.VideoResolutionPreset;
import com.microblink.blinkcard.uisettings.CameraSettings;

public final class BlinkCardOverlaySettingsSerialization implements OverlaySettingsSerialization {
@Override
Expand Down Expand Up @@ -57,6 +59,21 @@ public UISettings createUISettings(Context context, ReadableMap jsonUISettings,
if (errorCardTooCloseToEdge != null) {
overlayStringsBuilder.setErrorCardTooCloseToEdge(errorCardTooCloseToEdge);
}

VideoResolutionPreset videoResolutionPreset = VideoResolutionPreset.values()[0];
if (jsonUISettings.hasKey("androidCameraResolutionPreset")) {
videoResolutionPreset = VideoResolutionPreset.values()[jsonUISettings.getInt("androidCameraResolutionPreset")];
}

Boolean androidLegacyCameraApi = false;
if (jsonUISettings.hasKey("enableAndroidLegacyCameraApi")) {
androidLegacyCameraApi = jsonUISettings.getBoolean("enableAndroidLegacyCameraApi");
}

settings.setCameraSettings(new CameraSettings.Builder()
.setVideoResolutionPreset(videoResolutionPreset)
.setForceLegacyApi(androidLegacyCameraApi)
.build());

settings.setStrings(overlayStringsBuilder.build());
return settings;
Expand Down
Loading

0 comments on commit da0e04e

Please sign in to comment.