Skip to content

Commit

Permalink
3.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Jenkins committed Oct 27, 2021
1 parent 7217870 commit 34974d3
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 30 deletions.
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
# 3.1.0
### Added
* Added [LivenessResponse.guid](https://dev.regulaforensics.com/FaceSDK-iOS-Docs/Classes/RFSLivenessResponse.html#/c:objc(cs)RFSLivenessResponse(py)guid) – the id of the processing from the liveness service.
* **iOS**
* Added `RegulaCommon` – the internal shared library for Regula SDK products
* **Android**:
* Added possibility to intercept network connections between server and client to change HTTP request settings

### Fixed
* **iOS**:
* Fixed copying of `debug-symbols`. Only correct ones are copied to the `xcframework`.
* Fixed hold the `image` for `LivenessResponse` even when error happens.

### Changed
* Changed `hint.fit` for Spanish localization to `Coloque su rostro en el óvalo`.
* **iOS**:
* Changed camera settings to match `DocumentReader`'s. Used settings: `isSmoothAutoFocusEnabled`, `.continuousAutoWhiteBalance` and `.continuousAutoExposure`.
* **Android**:
* FaceCapture detection logic tweaked for better and easier photo capture

# 3.0.0
Flutter plugin that provides a solution for biometric verification by leveraging the power of Regula Face SDK Web Service. Biometric verification is the quickest and most reliable way to confirm any user’s identity and protect your business and your clients from fraud.

Expand Down
8 changes: 3 additions & 5 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,10 @@ rootProject.allprojects {
google()
jcenter()
maven {
url "http://maven.regulaforensics.com/RegulaDocumentReader"
allowInsecureProtocol true
url "https://maven.regulaforensics.com/RegulaDocumentReader"
}
maven {
url "http://maven.regulaforensics.com/RegulaDocumentReader/Beta"
allowInsecureProtocol true
url "https://maven.regulaforensics.com/RegulaDocumentReader/Beta"
}
}
}
Expand All @@ -46,7 +44,7 @@ android {

dependencies {
//noinspection GradleDependency
implementation('com.regula.face:api:3.0.1234'){
implementation('com.regula.face:api:3.1.1351'){
transitive = true
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import com.regula.facesdk.configuration.FaceCaptureConfiguration;
import com.regula.facesdk.configuration.LivenessConfiguration;
import com.regula.facesdk.configuration.MatchFaceConfiguration;

import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.plugin.common.MethodCall;
Expand Down Expand Up @@ -127,18 +128,24 @@ public void error(String s) {
case "stopLivenessProcessing":
stopLivenessProcessing(callback);
break;
case "presentFaceCaptureActivityByCameraId":
presentFaceCaptureActivityByCameraId(callback, args(0));
case "presentFaceCaptureActivityWithConfig":
presentFaceCaptureActivityWithConfig(callback, args(0));
break;
case "startLivenessByCameraId":
startLivenessByCameraId(callback, args(0));
case "startLivenessWithConfig":
startLivenessWithConfig(callback, args(0));
break;
case "setServiceUrl":
setServiceUrl(callback, args(0));
break;
case "matchFaces":
matchFaces(callback, args(0));
break;
case "setLanguage":
setLanguage(callback, args(0));
break;
case "matchFacesWithConfig":
matchFacesWithConfig(callback, args(0), args(1));
break;
}
} catch (Exception ignored) {
}
Expand Down Expand Up @@ -170,12 +177,28 @@ private void stopLivenessProcessing(Callback callback) {
callback.success();
}

private void presentFaceCaptureActivityByCameraId(Callback callback, int cameraID) {
Instance().presentFaceCaptureActivity(getContext(), new FaceCaptureConfiguration.Builder().setCameraId(cameraID).build(), (response) -> callback.success(JSONConstructor.generateFaceCaptureResponse(response).toString()));
private void presentFaceCaptureActivityWithConfig(Callback callback, JSONObject config) throws JSONException {
FaceCaptureConfiguration.Builder builder = new FaceCaptureConfiguration.Builder();
if(config.has("cameraId"))
builder.setCameraId(config.getInt("cameraId"));
if(config.has("cameraSwitchEnabled"))
builder.setCameraSwitchEnabled(config.getBoolean("cameraSwitchEnabled"));
if(config.has("showHelpTextAnimation"))
builder.setShowHelpTextAnimation(config.getBoolean("showHelpTextAnimation"));
Instance().presentFaceCaptureActivity(getContext(), builder.build(), (response) -> callback.success(JSONConstructor.generateFaceCaptureResponse(response).toString()));
}

private void startLivenessByCameraId(Callback callback, int cameraID) {
Instance().startLiveness(getContext(), new LivenessConfiguration.Builder().setCameraId(cameraID).build(), (response) -> callback.success(JSONConstructor.generateLivenessResponse(response).toString()));
private void startLivenessWithConfig(Callback callback, JSONObject config) throws JSONException {
LivenessConfiguration.Builder builder = new LivenessConfiguration.Builder();
if(config.has("attemptsCount"))
builder.setAttemptsCount(config.getInt("attemptsCount"));
if(config.has("cameraId"))
builder.setCameraId(config.getInt("cameraId"));
if(config.has("cameraSwitchEnabled"))
builder.setCameraSwitchEnabled(config.getBoolean("cameraSwitchEnabled"));
if(config.has("showHelpTextAnimation"))
builder.setShowHelpTextAnimation(config.getBoolean("showHelpTextAnimation"));
Instance().startLiveness(getContext(), builder.build(), (response) -> callback.success(JSONConstructor.generateLivenessResponse(response).toString()));
}

private void setServiceUrl(Callback callback, String url) {
Expand All @@ -186,4 +209,14 @@ private void setServiceUrl(Callback callback, String url) {
private void matchFaces(Callback callback, String request) throws JSONException {
Instance().matchFaces(JSONConstructor.MatchFacesRequestFromJSON(new JSONObject(request)), (response) -> callback.success(JSONConstructor.generateMatchFacesResponse(response).toString()));
}

private void matchFacesWithConfig(Callback callback, String request, JSONObject config) throws JSONException {
MatchFaceConfiguration.Builder builder = new MatchFaceConfiguration.Builder();
config.has("TODO"); // in order to remove warning Unused
Instance().matchFaces(JSONConstructor.MatchFacesRequestFromJSON(new JSONObject(request)), builder.build(),(response) -> callback.success(JSONConstructor.generateMatchFacesResponse(response).toString()));
}

private void setLanguage(Callback callback, @SuppressWarnings("unused") String language) {
callback.error("setLanguage() is an ios-only method");
}
}
71 changes: 61 additions & 10 deletions ios/Classes/FlutterFaceApiPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,18 @@ - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
[self stopFaceCaptureActivity :successCallback :errorCallback];
else if([action isEqualToString:@"stopLivenessProcessing"])
[self stopLivenessProcessing :successCallback :errorCallback];
else if([action isEqualToString:@"presentFaceCaptureActivityByCameraId"])
[self presentFaceCaptureActivityByCameraId :[args objectAtIndex:0] :successCallback :errorCallback];
else if([action isEqualToString:@"startLivenessByCameraId"])
[self startLivenessByCameraId :[args objectAtIndex:0] :successCallback :errorCallback];
else if([action isEqualToString:@"presentFaceCaptureActivityWithConfig"])
[self presentFaceCaptureActivityWithConfig :[args objectAtIndex:0] :successCallback :errorCallback];
else if([action isEqualToString:@"startLivenessWithConfig"])
[self startLivenessWithConfig :[args objectAtIndex:0] :successCallback :errorCallback];
else if([action isEqualToString:@"setServiceUrl"])
[self setServiceUrl :[args objectAtIndex:0] :successCallback :errorCallback];
else if([action isEqualToString:@"matchFaces"])
[self matchFaces :[args objectAtIndex:0] :successCallback :errorCallback];
else if([action isEqualToString:@"setLanguage"])
[self setLanguage :[args objectAtIndex:0] :successCallback :errorCallback];
else if([action isEqualToString:@"matchFacesWithConfig"])
[self matchFacesWithConfig :[args objectAtIndex:0] :[args objectAtIndex:1] :successCallback :errorCallback];
else
[self result:[NSString stringWithFormat:@"%@/%@", @"method not implemented: ", action] :errorCallback];
}
Expand Down Expand Up @@ -79,23 +83,59 @@ - (void) stopLivenessProcessing:(Callback)successCallback :(Callback)errorCallba
[self result:@"" :successCallback];
}

- (void) presentFaceCaptureActivityByCameraId:(NSNumber*)cameraId : (Callback)successCallback :(Callback)errorCallback{
[self result:@"this is an android-only method" :errorCallback];
- (void) presentFaceCaptureActivityWithConfig:(NSDictionary*)config :(Callback)successCallback :(Callback)errorCallback{
RFSFaceCaptureConfiguration *configuration = [RFSFaceCaptureConfiguration configurationWithBuilder:^(RFSFaceCaptureConfigurationBuilder * _Nonnull builder) {
if([config valueForKey:@"cameraSwitchEnabled"] != nil)
[builder setCameraSwitchEnabled:[[config valueForKey:@"cameraSwitchEnabled"] boolValue]];
if([config valueForKey:@"showHelpTextAnimation"] != nil)
[builder setEnableHintAnimation:[[config valueForKey:@"showHelpTextAnimation"] boolValue]];
if([config valueForKey:@"cameraPositionIOS"] != nil)
[builder setCameraPosition:[self RFSCameraPositionWithNSInteger:[[config valueForKey:@"cameraPositionIOS"] integerValue]]];
}];
dispatch_async(dispatch_get_main_queue(), ^{
[RFSFaceSDK.service presentFaceCaptureViewControllerFrom:[[[UIApplication sharedApplication] keyWindow] rootViewController] animated:true configuration: configuration onCapture:[self getFaceCaptureCompletion:successCallback :errorCallback] completion:nil];
});
}

- (void) startLivenessByCameraId:(NSNumber*)cameraId : (Callback)successCallback :(Callback)errorCallback{
[self result:@"this is an android-only method" :errorCallback];
- (void) startLivenessWithConfig:(NSDictionary*)config :(Callback)successCallback :(Callback)errorCallback{
RFSLivenessConfiguration *configuration = [RFSLivenessConfiguration configurationWithBuilder:^(RFSLivenessConfigurationBuilder * _Nonnull builder) {
if([config valueForKey:@"attemptsCount"] != nil)
[builder setAttemptsCount:[[config valueForKey:@"attemptsCount"] integerValue]];
if([config valueForKey:@"cameraSwitchEnabled"] != nil)
[builder setCameraSwitchEnabled:[[config valueForKey:@"cameraSwitchEnabled"] boolValue]];
if([config valueForKey:@"showHelpTextAnimation"] != nil)
[builder setEnableHintAnimation:[[config valueForKey:@"showHelpTextAnimation"] boolValue]];
if([config valueForKey:@"cameraPositionIOS"] != nil)
[builder setCameraPosition:[self RFSCameraPositionWithNSInteger:[[config valueForKey:@"cameraPositionIOS"] integerValue]]];
}];
dispatch_async(dispatch_get_main_queue(), ^{
[RFSFaceSDK.service startLivenessFrom:[[[UIApplication sharedApplication] keyWindow] rootViewController] animated:true configuration: configuration onLiveness:[self getLivenessCompletion:successCallback :errorCallback] completion:nil];
});
}

- (void) setServiceUrl:(NSString*)url : (Callback)successCallback :(Callback)errorCallback{
- (void) setServiceUrl:(NSString*)url :(Callback)successCallback :(Callback)errorCallback{
[RFSFaceSDK.service setServiceURL:url];
[self result:@"" :successCallback];
}

- (void) matchFaces:(NSString*)requestString : (Callback)successCallback :(Callback)errorCallback{
- (void) matchFaces:(NSString*)requestString :(Callback)successCallback :(Callback)errorCallback{
[RFSFaceSDK.service matchFaces:[RFSWJSONConstructor RFSMatchFacesRequestFromJSON:[NSJSONSerialization JSONObjectWithData:[requestString dataUsingEncoding:NSUTF8StringEncoding] options:0 error:NULL]] completion:[self getMatchFacesCompletion:successCallback :errorCallback]];
}

- (void) matchFacesWithConfig:(NSString*)requestString :(NSDictionary*)config :(Callback)successCallback :(Callback)errorCallback{
[RFSFaceSDK.service matchFaces:[RFSWJSONConstructor RFSMatchFacesRequestFromJSON:[NSJSONSerialization JSONObjectWithData:[requestString dataUsingEncoding:NSUTF8StringEncoding] options:0 error:NULL]] completion:[self getMatchFacesCompletion:successCallback :errorCallback]];
}

- (void) setLanguage:(NSString*)language :(Callback)successCallback :(Callback)errorCallback{
RFSFaceSDK.service.localizationHandler = ^NSString * _Nullable(NSString * _Nonnull localizationKey) {
NSString *result = NSLocalizedStringFromTable(localizationKey, language, @"");
if (![result isEqualToString:localizationKey])
return result;
return nil;
};
[self result:@"" :successCallback];
}

- (void (^)(RFSLivenessResponse * _Nonnull)) getLivenessCompletion:(Callback)successCallback :(Callback)errorCallback {
return ^(RFSLivenessResponse* response) {
[self result:[RFSWJSONConstructor dictToString:[RFSWJSONConstructor generateRFSLivenessResponse:response]] :successCallback];
Expand All @@ -114,4 +154,15 @@ - (void) matchFaces:(NSString*)requestString : (Callback)successCallback :(Callb
};
}

-(RFSCameraPosition)RFSCameraPositionWithNSInteger:(NSInteger)value {
switch(value){
case 0:
return RFSCameraPositionBack;
case 1:
return RFSCameraPositionFront;
default:
return RFSCameraPositionBack;
}
}

@end
4 changes: 2 additions & 2 deletions ios/flutter_face_api.podspec
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'flutter_face_api'
s.version = '3.0.0'
s.version = '3.1.0'
s.summary = 'A new flutter plugin project.'
s.description = <<-DESC
A new flutter plugin project.
Expand All @@ -13,6 +13,6 @@ A new flutter plugin project.
s.public_header_files = 'Classes/**/*.h'
s.dependency 'Flutter'
s.platform = :ios, '9.0'
s.dependency 'FaceSDK', '3.0.798'
s.dependency 'FaceSDK', '3.1.952'
s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' }
end
21 changes: 17 additions & 4 deletions lib/face_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,11 @@ class MatchFacesErrorCodes {
static const int PROCESSING_FAILED = 11;
}

class RFSCameraPosition {
static const int RFSCameraPositionBack = 0;
static const int RFSCameraPositionFront = 1;
}

class FaceSDK {
static const MethodChannel _channel = const MethodChannel('flutter_face_api/method');

Expand Down Expand Up @@ -378,12 +383,12 @@ class FaceSDK {
return await _channel.invokeMethod("stopLivenessProcessing", []);
}

static Future<dynamic> presentFaceCaptureActivityByCameraId(cameraId) async {
return await _channel.invokeMethod("presentFaceCaptureActivityByCameraId", [cameraId]);
static Future<dynamic> presentFaceCaptureActivityWithConfig(config) async {
return await _channel.invokeMethod("presentFaceCaptureActivityWithConfig", [config]);
}

static Future<dynamic> startLivenessByCameraId(cameraId) async {
return await _channel.invokeMethod("startLivenessByCameraId", [cameraId]);
static Future<dynamic> startLivenessWithConfig(config) async {
return await _channel.invokeMethod("startLivenessWithConfig", [config]);
}

static Future<dynamic> setServiceUrl(url) async {
Expand All @@ -393,4 +398,12 @@ class FaceSDK {
static Future<dynamic> matchFaces(request) async {
return await _channel.invokeMethod("matchFaces", [request]);
}

static Future<dynamic> setLanguage(language) async {
return await _channel.invokeMethod("setLanguage", [language]);
}

static Future<dynamic> matchFacesWithConfig(request, config) async {
return await _channel.invokeMethod("matchFacesWithConfig", [request, config]);
}
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: flutter_face_api
description:
This is a flutter module for compairing faces using phone`s camera.
version: 3.0.0
version: 3.1.0
homepage: "https://github.com/regulaforensics/flutter_face_api"

environment:
Expand Down

0 comments on commit 34974d3

Please sign in to comment.