TrustVision SDK is an iOS SDK for TrustVision Engine. It provides these features:

<key>NSCameraUsageDescription</key>
<string>Open camera</string>
pod 'TensorFlowLiteSwift', '~> 2.4.0'
pod 'PromiseKit', '~> 6.8'
pod 'CocoaLumberjack/Swift'
SWIFT_VERSION)-lc++ and -ObjC in Other linker flagsThe SDK provides some built in Activities example activity to capture id, selfie, liveness...
Initialize the sdk
TrustVisionSdk.shared.initialize(clientSettingsJsonString: nil, languageCode: "vi")
Options:
String. The jsonConfigurationByServer is optional but recommended.
It's the setting specialized for each client from TS server.
It's the response json string get by API https://ekyc.trustingsocial.com/api-reference/customer-api/#get-client-settings.
When it's null or unmatched with the expected type then the default setting in the SDK will be used.String. Language code. vi or enAllow user to change the sdk language after initialization
TrustVisionSdk.shared.changeLanguageCode(languageCode: String)
TrustVisionSdk.shared.getLanguageCode() -> String?
TrustVisionSdk.shared.getSupportedLanguageCodes() -> []
The id capturing activity will show the camera to capture image, preview the image. To start the id capturing activity.
let config = TVIdCardConfiguration(
cardType: selectedCardType,
cardSide: TVIdCardConfiguration.TVCardSide.front,
isSoundEnable: false,
isReadBothSide: false,
skipConfirmScreen: false,
isEnablePhotoGalleryPicker: false)
Options:
TVCardType. List of supported cards can be found by let cardTypes: [TSCardType] = try TrustVisionSdk.getCardTypes()TVCardSide. Card side to captureBool. Sound should be played or notBool. If true then the sdk will capture both side if possible; otherwise, then the card side defined in cardSide will be usedBool. Skip id capturing confirmation screen nor notBool. Allow user select id card image from phone gallerylet vc = TrustVisionSdk.shared.startIdCapturing(configuration: config, framesRecordedCallback: { batchId, frames, metadata, currentBatchIds in
}, success: { (result) in
}, failure: { (error) in
}, cancellation: {
// sdk is canceled
})
where:
configuration: TVIdCardConfiguration
framesRecordedCallback:
String. new coming local batch idDictionary. batch frame to pushDictionary. batch metadata to push[String]. For debugging onlyThis callback will be called each time there is a new frame batch coming. Client upload and get the batch id which is used for later id tampering api call.
success: method that will be called in case success. Parameters:
TVDetectionResult. Use the following fields:failure: FailureCallback
cancellation: CancellationCallback
With each batch that returned by framesRecordedCallback callback,
call the below api to get server frame batch id, keep it corresponds to batchId returned in framesRecordedCallback - local id
https://ekyc.trustingsocial.com/api-reference/customer-api/#upload-videoaudioframes
For example:
var frontCardFrameBatchIdsDictionary: [String: String] = [:]
var backCardFrameBatchIdsDictionary: [String: String] = [:]
. . .
framesRecordedCallback = { batchId, frames, metadata, currentBatchIds in
let batchDict = frames.merging(["metadata": metadata, "label": "The card type"]) { $1 }
let jsonToBeUploaded = try JSONSerialization.data(withJSONObject: batchDict, options: .prettyPrinted)
// upload frame batch to server using this api:
// https://ekyc.trustingsocial.com/api-reference/customer-api/#upload-videoaudioframes
doYourUploadFrameBatchHere(withJSON: jsonToBeUploaded) { uploadingResult in
// Keep the id that generated by the SDK corresponding with the one responded from server
if cardSide == TVIdCardConfiguration.TVCardSide.front {
frontCardFrameBatchIdsDictionary.updateValue(uploadingResult.fileId, forKey: batchId)
}
else {
backCardFrameBatchIdsDictionary.updateValue(uploadingResult.fileId, forKey: batchId)
}
}
}
For example:
// These lists contain all valid frame batch ids that responded by server
var validFrontCardServerFrameBatchIds: [String] = []
var validBackCardServerFrameBatchIds: [String] = []
private func removeRedudantFrameBatchIds(batchIdsDictionary: [String: String], validIdsFromSDK: [String]) -> [String] {
return batchIdsDictionary.compactMap({
if validIdsFromSDK.contains($0.key) {
return $0.value
}
else {
return nil
}
})
}
. . .
success = { result in
// result.frontCardFrameBatchIds && result.backCardFrameBatchIds is empty when Frame Recording feature is disabled by client settings.
// Wait until every Frame batch has been uploaded to server before calling this
if(everyFrameBatchUploadingCompleted) {
if (!result.frontCardFrameBatchIds.isEmpty) {
validFrontCardServerFrameBatchIds = removeRedudantFrameBatchIds(frontCardFrameBatchIdsDictionary, result.frontCardFrameBatchIds)
}
if (!result.backCardFrameBatchIds.isEmpty) {
validBackCardServerFrameBatchIds = removeRedudantFrameBatchIds(backCardFrameBatchIdsDictionary, result.backCardFrameBatchIds)
}
}
}
Use this API https://ekyc.trustingsocial.com/api-reference/customer-api/#upload-image The images should be uploaded as JPEG data with 100% quality. For example:
// with front side
let dataToUpload = result.frontIdImage.rawImage.jpegData(compressionQuality: 1.0) // 100% quality
let frontCardId = yourMethodToUploadImage(dataToUpload)
// with back side
let dataToUpload = result.backIdImage.rawImage.jpegData(compressionQuality: 1.0) // 100% quality
let backCardId = yourMethodToUploadImage(dataToUpload)
if result.frontIdQr.isRequired is true then result.frontIdQr.images array should be non-empty. Otherwise, clients should be warned to re-capture id card photos.
QR images will be uploaded with this api: https://ekyc.trustingsocial.com/api-reference/customer-api/#upload-image
let dataToUpload = result.frontIdQr.images[i].rawImage.jpegData(compressionQuality: 1.0) // 100% quality
let qrId = yourMethodToUploadImage(dataToUpload)
dataToUploadresult.frontIdQr.images[i].labelresult.frontIdQr.images[i].metadata*The same logic will be applied to result.backIdQr
Call this API https://ekyc.trustingsocial.com/api-reference/customer-api/#request-detect-id-card-tampering with params:
{
"image": {
"id": "<frontCardId>"
},
"image2": {
"id": "<backCardId>"
},
"qr1_images": [{
"id": "<qrId>"
}],
"card_type": "<result.cardType.id>",
"videos": [{
"id": "<validFrontCardServerFrameBatchIds[index]>"
},
{
"id": "<validFrontCardServerFrameBatchIds[index + 1]>"
},
...
{
"id": "<validBackCardServerFrameBatchIds[index]>"
},
{
"id": "<validBackCardServerFrameBatchIds[index + 1]>"
},
...
]
}
The selfie capturing activity will show the camera to capture image, preview the image and verify active liveness in local. To start the selfie capturing activity.
let config = TVSelfieConfiguration(
cameraOption: TVCameraOption.front,
isSoundEnable: true,
livenessMode: self.config.livenessMode,
skipConfirmScreen: false)
Options:
TVCameraOption. Set the camera modeBool. Sound should be played or notTVLivenessMode. Set the liveness verification modeBool. Skip selfie capturing confirmation screen or notlet vc = TrustVisionSdk.shared.startSelfieCapturing(configuration: config,
framesRecordedCallback: { batchId, frames, metadata, currentBatchIds in
}, success: { (result) in
}, failure: { (error) in
}, cancellation: {
// sdk is canceled
})
where:
configuration: TVSelfieConfiguration
framesRecordedCallback:
String. new coming local batch idDictionary. batch frame to pushDictionary. batch metadata to push[String]. For debugging onlyThis callback will be called each time there is a new frame batch coming. Client upload and get the batch id which is used for later selfie liveness api call.
success method that will be called in case success. Parameters:
TVDetectionResult . Use the following fields:failure: FailureCallback
cancellation: CancellationCallback
With each batch that returned by framesRecordedCallback callback,
call the below api to get server frame batch id, keep it corresponds to batchId returned in framesRecordedCallback - local id
https://ekyc.trustingsocial.com/api-reference/customer-api/#upload-videoaudioframes
For example:
// this dictionary will be used for Liveness verification
var selfieFrameBatchIdsDictionary: [String: String] = [:]
. . .
framesRecordedCallback = { batchId, frames, metadata, currentBatchIds in
let batchDict = frames.merging(["metadata": metadata, "label": "video"]) { $1 }
let jsonToBeUploaded = try JSONSerialization.data(withJSONObject: batchDict, options: .prettyPrinted)
// upload frame batch to server using this api:
// https://ekyc.trustingsocial.com/api-reference/customer-api/#upload-videoaudioframes
doYourUploadFrameBatchHere(withJSON: jsonToBeUploaded) { uploadingResult in
// Keep the id that generated by the SDK corresponding with the one responded from server
selfieFrameBatchIdsDictionary.updateValue(uploadingResult.fileId, forKey: batchId)
}
}
For example:
// These lists contain all valid frame batch ids that responded by server
var validServerFrameBatchIds: [String] = []
private func removeRedudantFrameBatchIds(batchIdsDictionary: [String: String], validIdsFromSDK: [String]) -> [String] {
return batchIdsDictionary.compactMap({
if validIdsFromSDK.contains($0.key) {
return $0.value
}
else {
return nil
}
})
}
. . .
success = { result in
// result.livenessFrameBatchIds is empty when Frame Recording feature is disabled by client settings.
// Wait until every Frame batch has been uploaded to server before calling this
if(everyFrameBatchUploadingCompleted) {
if (!result.livenessFrameBatchIds.isEmpty) {
validServerFrameBatchIds = removeRedudantFrameBatchIds(selfieFrameBatchIdsDictionary, result.livenessFrameBatchIds)
}
}
}
https://ekyc.trustingsocial.com/api-reference/customer-api/#upload-image The images should be uploaded as JPEG data with 100% quality. For example:
// with frontal images
let dataToUpload = result.selfieImages[i].frontalImage.rawImage.jpegData(compressionQuality: 1.0) // 100% quality
// with gesture images
let dataToUpload = result.selfieImages[i].gestureImage.rawImage.jpegData(compressionQuality: 1.0) // 100% quality
id of frontal image i = image id of result.selfieImages[i].frontalImage.rawImage
id of gesture image i = image id of result.selfieImages[i].gestureImage.rawImage
https://ekyc.trustingsocial.com/api-reference/customer-api/#upload-videoaudioframes
id of selfie video i = video id of result.livenessVideos[i]
API document: https://ekyc.trustingsocial.com/api-reference/customer-api/#verify-face-liveness
Call the above api with below parameters:
images field{
"images": [
{
"id": "<result.selfieImages[index].frontalImage.imageId>"
},
{
"id": "<result.selfieImages[index + 1].frontalImage.imageId>"
},
...
]
}
gesture_images field{" "}{
"gesture_images": [
{
"gesture": "<result.selfieImages[index].gestureType.description>",
"images": [{
"id": "<result.selfieImages[index].gestureImage.imageId>"
}]
},
{
"gesture": "<result.selfieImages[index + 1].gestureType.description>",
"images": [{
"id": "<result.selfieImages[index + 1].gestureImage.imageId>"
}]
},
...
]
}
videos field{
"videos": [
{
"id": "<validServerFrameBatchIds[index]>"
},
{
"id": "<validServerFrameBatchIds[index + 1]>"
},
...
]
}
metadata field{" "}{
"metadata": "<result.livenessMetadata>"
}
| Properties | Type | description |
|---|---|---|
frontIdImage | TVEncryptedImage | Image of id card's front side (use field rawImage) |
backIdImage | TVEncryptedImage | Image of id card's back side (use field rawImage) |
frontIdQr | TVCardQr | Info of QR of id card's front side |
backIdQr | TVCardQr | Info of QR of id card's back side |
frontCardFrameBatchIds | [String] | List of front id frame batch IDs |
backCardFrameBatchIds | [String] | List of back id frame batch IDs |
| Properties | Type | description |
|---|---|---|
livenessResult | TVLivenessResult | Liveness check result |
selfieImages | [TVGestureImage] | Images of selfie |
livenessFrameBatchIds | [String] | List of selfie frame batch IDs |
livenessVideos | [Data] | List of video data during checking liveness |
livenessMetadata | [String: Any]? | Collected data during liveness checking process |
Will be called in case failed. Parameters:
TVError.Will be called in case the sdk is cancelled. No parameters