• About TrustVision
  • Android SDK
  • Flutter SDK
  • React Native SDK
  • Web SDK
  • API Client Libraries
  • eKYC Platform
  • Integration Case Studies
  • TS eKYC/FA App
TrustVision API Documentation

iOS 2.1.x UI only

OVERVIEW

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

  • ID and selfie matching.
  • Liveness checking.

Specifications

  • Xcode version 10.2+
  • target iOS version 9+
  • swift version: 5

Integration Steps

1. Adding the SDK to your project

  • Drag all file *.framework and *.bundle into project
alt text
  • Add key to info.plist:
groovy
    <key>NSCameraUsageDescription</key>
    <string>Open camera</string>
  • Add dependencies
    • Use CocoaPods, add these lines to podfile
    pod 'TensorFlowLiteSwift', '~> 2.4.0'
    pod 'PromiseKit', '~> 6.8'
    pod 'CocoaLumberjack/Swift'
  • If host app is using Objective-C, please follow these additional steps:
    • add a empty swift file and create bridging file (to force project create key SWIFT_VERSION)
    • add flag -lc++ and -ObjC in Other linker flags

2. Start the SDK

The SDK provides some built in Activities example activity to capture id, selfie, liveness...

2.0. Initialize SDK

Initialize the sdk

swift
  TrustVisionSdk.shared.initialize(clientSettingsJsonString: nil, languageCode: "vi")

Options:

  • clientSettingsJsonString: 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.
  • languageCode: String. Language code. vi or en

2.1. Update and get sdk language

Allow user to change the sdk language after initialization

swift
TrustVisionSdk.shared.changeLanguageCode(languageCode: String)
TrustVisionSdk.shared.getLanguageCode() -> String?
TrustVisionSdk.shared.getSupportedLanguageCodes() -> []

2.2. Capture the ID

The id capturing activity will show the camera to capture image, preview the image. To start the id capturing activity.

2.2.1. Set config parameters
swift
let config = TVIdCardConfiguration(
                cardType: selectedCardType,
                cardSide: TVIdCardConfiguration.TVCardSide.front,
                isSoundEnable: false,
                isReadBothSide: false,
                skipConfirmScreen: false,
                isEnablePhotoGalleryPicker: false)

Options:

  • cardType: TVCardType. List of supported cards can be found by let cardTypes: [TSCardType] = try TrustVisionSdk.getCardTypes()
  • cardSide: TVCardSide. Card side to capture
  • isEnableSound: Bool. Sound should be played or not
  • isReadBothSide: Bool. If true then the sdk will capture both side if possible; otherwise, then the card side defined in cardSide will be used
  • skipConfirmScreen: Bool. Skip id capturing confirmation screen nor not
  • isEnablePhotoGalleryPicker: Bool. Allow user select id card image from phone gallery
2.2.2. Start id capturing from configuration
swift
let 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:

    • batchId: String. new coming local batch id
    • frames: Dictionary. batch frame to push
    • metadata: Dictionary. batch metadata to push
    • currentBatchIds [String]. For debugging only

    This 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:

    • result: TVDetectionResult. Use the following fields:
      • frontIdImage
      • backIdImage
  • failure: FailureCallback

  • cancellation: CancellationCallback

2.2.3. Handle framesRecordedCallback callback

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:

swift
  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)
      }
    }
  }
2.2.4. Handle ID capturing results
2.2.4.1. Remove redundant frame batch ids

For example:

swift
// 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)
        }
    }
}
2.2.4.2. Get Image Ids to be used in a particular use case

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:

swift
// 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)
2.2.4.3. Upload QR images

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

swift
let dataToUpload = result.frontIdQr.images[i].rawImage.jpegData(compressionQuality: 1.0) // 100% quality
let qrId = yourMethodToUploadImage(dataToUpload)
  • Fields:
    • data: dataToUpload
    • label: result.frontIdQr.images[i].label
    • metadata: result.frontIdQr.images[i].metadata

*The same logic will be applied to result.backIdQr

2.2.4.4. Call this api to check id tampering

Call this API https://ekyc.trustingsocial.com/api-reference/customer-api/#request-detect-id-card-tampering with params:

json
{
    "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]>"
      },
      ...
    ]
}

2.3. Capture the selfie

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.

2.3.1. Set config parameters
swift
let config = TVSelfieConfiguration(
                cameraOption: TVCameraOption.front,
                isSoundEnable: true,
                livenessMode: self.config.livenessMode,
                skipConfirmScreen: false)

Options:

  • cameraOption: TVCameraOption. Set the camera mode
  • isSoundEnable: Bool. Sound should be played or not
  • livenessMode: TVLivenessMode. Set the liveness verification mode
  • skipConfirmScreen: Bool. Skip selfie capturing confirmation screen or not
2.3.2. Start selfie capturing from configuration
swift
let 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:

    • batchId: String. new coming local batch id
    • frames: Dictionary. batch frame to push
    • metadata: Dictionary. batch metadata to push
    • currentBatchIds [String]. For debugging only

    This 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:

    • result : TVDetectionResult . Use the following fields:
      • selfieImages
  • failure: FailureCallback

  • cancellation: CancellationCallback

2.3.3. Handle framesRecordedCallback callback

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:

swift
  // 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)
    }
  }
2.3.4. Handle selfie capturing results
2.3.4.1. Remove redundant frame batch ids

For example:

swift
// 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)
        }
    }
}
2.3.4.2 . Use this api to get image id:

https://ekyc.trustingsocial.com/api-reference/customer-api/#upload-image The images should be uploaded as JPEG data with 100% quality. For example:

swift
// 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

2.3.4.3. Use this api to get video id:

https://ekyc.trustingsocial.com/api-reference/customer-api/#upload-videoaudioframes id of selfie video i = video id of result.livenessVideos[i]

2.3.4.4. Call this api to check liveness

API document: https://ekyc.trustingsocial.com/api-reference/customer-api/#verify-face-liveness

Call the above api with below parameters:

  1. images field
json
{
  "images": [
    {
      "id": "<result.selfieImages[index].frontalImage.imageId>"
    },
    {
      "id": "<result.selfieImages[index + 1].frontalImage.imageId>"
    },
    ...
  ]
}
  1. gesture_images field{" "}
json
{
  "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>"
      }]
    },
    ...
  ]
}
  1. videos field
json
{
  "videos": [
    {
      "id": "<validServerFrameBatchIds[index]>"
    },
    {
      "id": "<validServerFrameBatchIds[index + 1]>"
    },
    ...
  ]
}
  1. metadata field{" "}
json
{
  "metadata": "<result.livenessMetadata>"
}

API references

1. TVDetectionResult

PropertiesTypedescription
frontIdImageTVEncryptedImageImage of id card's front side (use field rawImage)
backIdImage TVEncryptedImageImage of id card's back side (use field rawImage)
frontIdQrTVCardQrInfo of QR of id card's front side
backIdQr TVCardQrInfo 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
PropertiesTypedescription
livenessResult TVLivenessResultLiveness 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

2. TVGestureImage

  • gestureType: GestureType
  • frontalImage: TVEncryptedImage
  • gestureImage: TVEncryptedImage

3. TVGestureImage.GestureType

  • up
  • down
  • left
  • ight
  • frontal

4. TVCameraOption (Enum)

  • TVCameraOption.front: Use front camera
  • TVCameraOption.back: Use back camera
  • TVCameraOption.both: The screen will have a button to switch between front & back camera

5. TVLivenessMode (Enum)

  • TVLivenessMode.none: no liveness verification. Just capture the selfie and verify sanity.
  • TVLivenessMode.passive: Use texture-based approach.
  • TVLivenessMode.active: Use challenge-response approach. User needs to follow and finish all steps when capturing selfie like turn left, right, up, smile, open mouth...

6. TVLivenessResult

  • isLive: selfie is live or not

7. TVCardQr

  • isRequired: This side of card contains QR or not
  • images: [TVEncryptedImage]. Array of QR images

8. FailureCallback (Callback)

Will be called in case failed. Parameters:

  • error: TVError.
    • errorCode: the specific error code.
    • description: the human-readable error description can be show to end user

9. CancellationCallback (Callback)

Will be called in case the sdk is cancelled. No parameters