Compatibility & Lib Size

  • This version is compatible with portrait orientation for all devices iOS 13+ and iPadOS 13+.
  • This version can install on iOS 11 but it can't work and need to add version checking.

Library Lib will add around ~10MB to your application in thining mode (The real download size on App Store )

Remark:
NFC will be supported by iPhone only due to hardware limitations.


Liveness License

To make the LiveNess feature work, EkycSDK check the app License based on IOS Bundle ID, so please contact our support team to support the new bundle ID.

If POC, please use com.ekyc.sdk.* format as your test project Bundle ID


Current Version

Mac EKYC Core: 1.11.4

Releases Notes


SDK Integration

Using Pod

  1. In your Podfile, add pod 'AppManEKYC', :git => 'https://{{provided github token}}@github.com/appman-agm/AppManEKYC.git', :tag => '{{version}}' then run pod install.

  2. Example:

    platform :ios, '13.0'
    
    target 'TestEKYC-POD' do
      use_frameworks!
      pod 'AppManEKYC', :git => 'https://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@github.com/appman-agm/AppManEKYC.git', :tag => '{{version}}'
    end
    

Configure Info Plist

  • Camera:
  • Location (to get user location for dip chip flow)

If we don't use DipChip flow, please refer to Turn off DipChip Flow but still need to add Location privacy to info.plist to pass the Apple Review process.

  • Photo (to save QR code for dipchip flow) (optional):
  • NFC (optional):

Info.plist XML scripts

<dict>
    <key>NFCReaderUsageDescription</key>
    <string>This app uses NFC to scan passports</string>
    <key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
    <array>
        <string>A0000002471001</string>
        <string>A0000002472001</string>
        <string>00000000000000</string>
    </array>

    <key>NSPhotoLibraryUsageDescription</key>
    <string>This app requires this permission to save DipChip QRCode</string>
    <key>NSPhotoLibraryAddUsageDescription</key>
    <string>This app requires this permission to save DipChip QRCode</string>

    <key>NSLocationWhenInUseUsageDescription</key>
    <string>This app requires location for DipChip feature</string>

    <key>NSCameraUsageDescription</key>
    <string>Need Camera for OCR</string>
</dict>

Usage

Start EKYC process

  1. Add import MaCEKYC_FT to your swift file.

  2. Set configuration for tenantConfigClientName, baseURL, tenantConfigURL, ekycURL, verificationID, livenessSuccessText and isThaiOnly (language):

    - Production environment

     var ekycConfiguration = EKYCConfiguration()
     ekycConfiguration.tenantConfigClientName = "{{clientName}}"
     ekycConfiguration.baseURL = "https://mac-portal.mac.appmanteam.com/api/{{version}}/kyc"
     ekycConfiguration.tenantConfigURL = "https://mac-portal.mac.appmanteam.com/api/v1/tenant-config"
     ekycConfiguration.ekycURL =  "https://{{clientName}}.mac.appmanteam.com/apps/identity-verification"
     ekycConfiguration.verificationID = "{{verificationID}}"
     ekycConfiguration.livenessSuccessText = LivenessSuccessText() // Set it if you want to change the Success text in Liveness screen
     ekycConfiguration.isThaiOnly = true
     ekycConfiguration.enableSecurityProtection = true // Default is false
     ekycConfiguration.enableManualCaptureMode = false // Default is false, SDK will using ML and auto capture 
              // when detected IDCard frame (Both Normal/ Hologram mode)
     EKYCService.shared.setConfiguration(configuration: ekycConfiguration)
    
  3. Start EKYC:

    EKYCService.shared.startMainViewController(controller: self, frame: frame)
    

🚧

If you use UIKit, EKYCService.shared.startMainViewController(controller: self, frame: frame) should be in viewDidLoad()

EKYC Delegate

In override func viewDidLoad() add:

EKYCService.shared.delegate = self

then make the class implement EKYCDelegate to override these functions:

extension ViewController: EKYCDelegate {
    
    // When EKYC started
    func onEkycStarted() {}
    
    // When EKYC stopped
    func onEkycStopped() {}
    
    // When EKYC has error (general, security, sslPinning)
    func onEkycError(error: EError) {}

    // Get status of EKYC url (verified, completed, expired, retry)
    func onEkycStatus(status: EStatus, payload: [String : Any]) {}
}

📘

To track EKYC status, please refer this section:

Tracking EKYC status

Stop/Remove EKYC view

EKYCService.shared.stopMainViewController()
let items = [APMSecurityItem]()
EKYCService.shared.turnOffItems(items: items)

Avoid location permission asking popup

if your requirement don't want to use dipchip flow please add below code to avoid asking location permission popup

EKYCService.shared.turnOffDipchipFlow()

enableManualCaptureMode

if you are using auto capture for ocr, and want to disable auto capture you can set enableManualCaptureMode to true.

	ekycConfiguration.enableManualCaptureMode = true

Turn off DipChip flow

On IOS, it takes a very long time to fetch the location to submit on DipChip flow, so EkycSDK requests the location when starting Ekyc process (The Location request popup will shown at this time).

We can turn off this feature by calling EKYCService.shared.turnOffDipchipFlow()before startMainViewController. This also makes the Location request popup not show.

Start LiveNess Match Checker process

EkycSDK also supports doing the LiveNess process only to recheck the Liveness with the current EKYC result

LiveNess required parameters

To start the liveness process, we need setup EKYCConfiguration object with these parameters (All is required)

- Production environment

 var ekycConfiguration = EKYCConfiguration()
 ekycConfiguration.tenantConfigClientName = "{{clientName}}"
 ekycConfiguration.baseURL = "https://mac-portal.mac.appmanteam.com/api/{{version}}/kyc"
 ekycConfiguration.tenantConfigURL = "https://mac-portal.mac.appmanteam.com/api/v1/tenant-config"
 ekycConfiguration.ekycURL =  "https://{{clientName}}.mac.appmanteam.com/apps/identity-verification"
 ekycConfiguration.verificationID = "{{verificationID}}"
 ekycConfiguration.livenessSuccessText = LivenessSuccessText() // Set it if you want to change the Success text in Liveness screen
 ekycConfiguration.isThaiOnly = true
 ekycConfiguration.enableSecurityProtection = true // Default is false
 EKYCService.shared.setConfiguration(configuration: ekycConfiguration)

Liveness Securities

LiveNess standalone process also supports Security stuff by turning on EKYCConfiguration.enableSecurityProtection same as EKYC flow

Start Liveness Match Checker

For next step, call the start function in LiveNessMatchChecker

 LiveNessMatchChecker.shared.start(rootViewController: self, ekycConfiguration: ekycConfiguration, delegate: self)

Liveness Delegate

All Liveness events will be notified through theLiveNessCheckDelegate.

        public protocol LiveNessCheckDelegate {
           func onLiveNessStarted()
           func onLiveNessError(_ liveNessMatchError: LiveNessMatchError)
           func onLiveNessStatus(livenessStatus: LiveNessMatchStatus)
       }

Liveness Started event

The onLiveNessStarted event will be notified after LiveNessMatchChecker.start() is called without any setup error

Liveness Status event

Notify the Liveness Status includes: Completed, UserCancel through onLiveNessStatus(liveNessMatchStatus: LiveNessMatchStatus).

📘

Completed Status

This status will be notified in these cases

  • User completely finish the liveness 3d compare

📘

UserCancel status

This status will be notified in these cases

  • User close liveness screen without finish liveness

Liveness Error event

We support following error cases in Liveness SDK (The Error is one instance of LiveNessMatchError)

  1. MissingConfiguration

    If we missing any parameter of EkycConfig, this error also notify the configurationName to pointed out which param is missing

      public func onLiveNessError(_ liveNessMatchError: LiveNessMatchError) {
               switch liveNessMatchError {
                ...
                case .MissingConfiguration(let config):
                  print(config)
         }
  1. SSLPiningError
    Trigger when SSLPining not passed
onLiveNessError(SSLPiningError)
  1. SecurityError
    This error also include which EKYCSecurityItem not passed when do Security Check
onLiveNessError(SecurityError)
  1. TenanConfigError
    Trigger when get tanant config failed
onLiveNessError(TenanConfigError)
  1. GetCredentialsError
    Trigger when get credentials failed
onLiveNessError(GetCredentialsError)
  1. LivenessSetupError
    Trigger when can't initialize liveness SDK
onLiveNessError(LivenessSetupError)
  1. CannotGetLiveNessToken
    Trigger when get token liveness fail
onLiveNessError(CannotGetLiveNessToken)
  1. EkycMissing
    Trigger when missing liveness from EKYC flow. Should be finish EKYC before do liveness match checker.
onLiveNessError(EkycMissing)
  1. UnknownError
    Trigger when get other error with error message
         public func onLiveNessError(_ liveNessMatchError: LiveNessMatchError) {
               switch liveNessMatchError {
                ...
                case .UnknownError(let msg):
                  print("UnknownError \(msg))
         }

SDK Security

AppManEKYC provides a mechanism to secure applications with these protections:

APMSecurityItemDescriptionError CodeSub Error Code
EMULATORThis device is emulator10
JAILBROKENThis device is jailbroken20
DEBUGThis device is attaching to debugger30
REVERSE_TOOLSThis device has evidence of reverse engineering40
PROXYThis device is acted as a proxy50
  • Update Info.plist (Optional, the app can run normally without this)

There is a check in jailbreak detection module that uses canOpenURL(_:) method and requires specifying URLs that will be queried.

<key>LSApplicationQueriesSchemes</key>
<array>
    <string>undecimus</string>
    <string>sileo</string>
    <string>zbra</string>
    <string>filza</string>
    <string>activator</string>
</array>
  • Enable Security:

ekycConfiguration.enableSecurityProtection = true
  • Skip the security item in the list: import APMSecurity, then:

let items = [APMSecurityItem]()
EKYCService.shared.turnOffItems(items: items)
let items = [APMSecurityItem]()
LiveNessMatchChecker.shared.turnOffItems(items: items)

Third-party libraries

EKYC SDK also uses third-party libraries to build its features, these are some libraries inside and their version:

NameVersion
CocoaLumberjack3.8.2

Example Project

Refer to this Example App to see how EkycSDK work

git clone https://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@github.com/appman-agm/mac-identity-verification-ios-example.git

FAQs

Build time errors

Q: How can I resolve this kind of compile error?

👍

A:

  • Add this code block to your Podfile. Remove Pods folder and Podfile.lock and then run pod install again
post_install do |installer|
  installer.generated_projects.each do |project|
    project.targets.each do |target|
      target.build_configurations.each do |config|
        config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '12.0'
        if target.name == 'Sentry'
          config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0'
        end
        if target.name == 'SentryPrivate'
            config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0'
        end
        if target.name == 'IOSSecuritySuite'
            config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '11.0'
        end
      end
    end
  end
end

So your final Podfile will be like this

Feature behavior issues

Q: I got infinite recursive loop when finished capture image. How can I fix it?

👍

A:

To fix recursive loop to capture image, this function

EKYCService.shared.startMainViewController(controller: self, frame: frame)

should not be called in viewDidAppear(:)_ which will be triggered this function every time after camera gone because of ViewController life cycle