Download the demo project and extract it, then open this project using Visual Studio.
Modify the MainPage.xaml.cs
to specify your market
and license content
(The license content is obtained by your server calling our openapi).
// Specify your market and isGlobalService:
// market: Indonesia, India, Philippines, Vietnam, Thailand, Mexico, Malaysia,
// Pakistan, Nigeria, Laos, Cambodia, Myanmar, Singapore, Canada, America, UnitedKingdom, Colombia
// isGlobalService: true if you enabled Global service, otherwise false
liveness.initSDK("your-market", false);
// Specify your license. The license content is obtained by your server calling our openapi
var license = "your-license";
var resultStr = liveness.setLicenseAndCheck(license);
Run project XamarinFormsDemo01.iOS
on your iPhone device.
Integrate the SDK into your project:
NuGet
source https://public-n3.advai.net/repository/nuget-hosted/
.AdvanceAI.iOS.Liveness
.Add camera and motion sensor (gyroscope) usage description in Info.plist
as bellow. Ignore this step if you have added those.
<key>NSCameraUsageDescription</key>
<string>Use the camera to detect the face movements</string>
<key>NSMotionUsageDescription</key>
<string>Use the motion sensor to get the phone orientation</string>
New interface ILivenessService.cs
to your XamarinForms
project:
using System;
namespace AdvanceAI.Liveness.Services
{
public class Result {
public bool isSucceed;
public String base64Image;
public String livenessId;
public String transactionId;
public String errorCode;
public String errorMsg;
}
public interface ILivenessService
{
void initSDK(String market, bool isGlobalService);
String setLicenseAndCheck(String license);
void showSDKPage(Action<Result> resultCallback);
}
}
New IOSLivenessService.cs
to your XamarinForms.iOS
project:
using System;
using System.Collections.Generic;
using AdvanceAI.Liveness.Services;
[assembly: Xamarin.Forms.Dependency(typeof(AdvanceAI.iOS.Liveness.Services.IOSLivenessService))]
namespace AdvanceAI.iOS.Liveness.Services
{
using AdvanceAI.iOS.Liveness.Core;
using AdvanceAI.iOS.Liveness.UI;
using Foundation;
using UIKit;
public class IOSLivenessService : ILivenessService
{
private Action<Result> mResultCallback;
public IOSLivenessService()
{
}
/// <summary>
/// Initialize SDK
/// </summary>
/// <param name="market"> Note "market" string is case-insensitive </param>
/// <param name="isGlobalService"></param>
void ILivenessService.initSDK(string market, bool isGlobalService)
{
var rawMarket = AAILivenessMarket.Indonesia;
switch (market.ToLower())
{
case "indonesia":
rawMarket = AAILivenessMarket.Indonesia;
break;
case "india":
rawMarket = AAILivenessMarket.India;
break;
case "philippines":
rawMarket = AAILivenessMarket.Philippines;
break;
case "vietnam":
rawMarket = AAILivenessMarket.Vietnam;
break;
case "thailand":
rawMarket = AAILivenessMarket.Thailand;
break;
case "mexico":
rawMarket = AAILivenessMarket.Mexico;
break;
case "malaysia":
rawMarket = AAILivenessMarket.Malaysia;
break;
case "pakistan":
rawMarket = AAILivenessMarket.Pakistan;
break;
case "nigeria":
rawMarket = AAILivenessMarket.Nigeria;
break;
case "laos":
rawMarket = AAILivenessMarket.Laos;
break;
case "cambodia":
rawMarket = AAILivenessMarket.Cambodia;
break;
case "myanmar":
rawMarket = AAILivenessMarket.Myanmar;
break;
case "singapore":
rawMarket = AAILivenessMarket.Singapore;
break;
case "canada":
rawMarket = AAILivenessMarket.Canada;
break;
case "america":
rawMarket = AAILivenessMarket.America;
break;
case "unitedkingdom":
rawMarket = AAILivenessMarket.UnitedKingdom;
break;
case "colombia":
rawMarket = AAILivenessMarket.Colombia;
break;
default:
break;
}
AAILivenessSDK.InitWithMarket(rawMarket, isGlobalService);
// If you want to do additional settings,
// please refer to the native sdk documentation
// https://doc.advance.ai/sdk/ios/liveness/en/standard.html#usage
/*
// e.g.
AAILivenessSDK.AdditionalConfig.DetectionLevel = AAIDetectionLevel.Easy;
*/
/*
// e.g. Customize the size of the resulting image. Image size(width) should be in range [300, 1000].
AAILivenessSDK.ConfigResultPictureSize(600);
*/
/*
// e.g. Set whether to detect face occlusion. The default value is false.
AAILivenessSDK.ConfigDetectOcclusion(true);
*/
}
string ILivenessService.setLicenseAndCheck(string license)
{
return AAILivenessSDK.ConfigLicenseAndCheck(license);
}
void ILivenessService.showSDKPage(Action<Result> resultCallback)
{
mResultCallback = resultCallback;
var livenessVC = new AAILivenessViewController();
livenessVC.RecordUserGiveUp = true;
// If you want to do additional configuration for this livenessVC,
// please refer to the native sdk documentation
// https://doc.advance.ai/sdk/ios/liveness/en/standard.html#usage
/*
// e.g. Set the timeout for prepare stage, default is 10s.
livenessVC.PrepareTimeoutInterval = 20;
*/
// Success callback
livenessVC.DetectionSuccessBlk = (rawVC, rawResult) =>
{
String base64ImgStr = rawResult.Img.AsJPEG(1).GetBase64EncodedString(NSDataBase64EncodingOptions.None);
// 1. Close SDK page
rawVC.NavigationController.PresentingViewController.DismissViewController(true, () =>
{
// 2. Here we have to release the related objects immediately,
// otherwise the SDK may have undefined behavior.
// (C#'s garbage collection mechanism prevents these objects from being released immediately)
rawVC.NavigationController.Dispose();
rawVC.Dispose();
// 3. Callback
var result = new Result();
result.isSucceed = true;
result.transactionId = rawResult.TransactionId;
result.livenessId = rawResult.LivenessId;
result.base64Image = base64ImgStr;
mResultCallback(result);
});
};
// Failure callback
livenessVC.DetectionFailedBlk = (rawVC, rawErrorInfo) =>
{
var failedResult = AAILivenessFailedResult.ResultWithErrorInfo(rawErrorInfo);
// 1. Close SDK page
rawVC.NavigationController.PresentingViewController.DismissViewController(true, () =>
{
// 2. Here we have to release the related objects immediately,
// otherwise the SDK may have undefined behavior.
// (C#'s garbage collection mechanism prevents these objects from being released immediately)
rawVC.NavigationController.Dispose();
rawVC.Dispose();
// 3. Callback
var result = new Result();
result.isSucceed = false;
result.errorCode = failedResult.ErrorCode;
result.errorMsg = failedResult.ErrorMsg;
result.transactionId = failedResult.TransactionId;
mResultCallback(result);
});
};
// Present liveness SDK page
var navc = new UINavigationController(livenessVC);
navc.NavigationBarHidden = true;
navc.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
var keyWindow = UIApplication.SharedApplication.KeyWindow;
var rootVC = keyWindow.RootViewController;
rootVC.PresentViewController(navc, true, null);
}
}
}
In your XamarinForms
project, specify your market
and license
content, then show SDK page :
void OnButtonClicked(object sender, EventArgs args)
{
if (DeviceInfo.Platform == DevicePlatform.iOS)
{
// Show iOS liveness page
showLivenessPage();
}
else if (DeviceInfo.Platform == DevicePlatform.Android)
{
// Show android liveness page
Console.WriteLine("TODO: Show android liveness page.....");
}
}
void showLivenessPage()
{
var liveness = Xamarin.Forms.DependencyService.Get<ILivenessService>();
// Specify your market and isGlobalService:
// market: Indonesia, India, Philippines, Vietnam, Thailand, Mexico, Malaysia,
// Pakistan, Nigeria, Laos, Cambodia, Myanmar, Singapore, Canada, America, UnitedKingdom, Colombia
// isGlobalService: true if you enabled Global service, otherwise false
liveness.initSDK("Indonesia", false);
// Specify your license. The license content is obtained by your server calling our openapi
var license = "your-license";
var resultStr = liveness.setLicenseAndCheck(license);
if (resultStr == "SUCCESS")
{
liveness.showSDKPage((result) =>
{
if (result.isSucceed)
{
Console.WriteLine("Detection succeed! LivenessId:{0}", result.livenessId);
}
else
{
Console.WriteLine("Detection failed! errorCode: {0}. errorMsg: {1}. transactionId: {2}", result.errorCode, result.errorMsg, result.transactionId);
}
});
}
else
{
Console.WriteLine("License check failed: {0}", resultStr);
}
}
The errorCode
values of Result
are as follows:
errorCode | raw native sdk code | Description |
---|---|---|
PREPARE_TIMEOUT | fail_reason_prepare_timeout | Timeout during the preparation stage |
ACTION_TIMEOUT | fail_reason_timeout | Timeout during the motion stage |
MUTI_FACE | fail_reason_muti_face | Multiple faces detected during the motion stage |
FACE_MISSING | fail_reason_facemiss_blink_mouth | Face is missing during the motion stage(blink or open mouth) |
FACE_MISSING | fail_reason_facemiss_pos_yaw | Face is missing during the motion stage(pos yaw) |
MUCH_ACTION | fail_reason_much_action | Multiple motions detected during the motion stage |
USER_GIVE_UP | user_give_up | The user clicked the top left back button during the detection process |
NO_RESPONSE | Network request failed | |
UNDEFINED | Other undefined errors | |
...(Other server side error codes) |