EKYC-iOS
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
SDK Integration
Using Pod
-
In your Podfile, add
pod 'AppManEKYC', :git => 'https://{{provided github token}}@github.com/appman-agm/AppManEKYC.git', :tag => '{{version}}'
then run pod install. -
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
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
-
Add
import MaCEKYC_FT
to your swift file. -
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)
-
Start EKYC:
EKYCService.shared.startMainViewController(controller: self, frame: frame)
If you use UIKit,
EKYCService.shared.startMainViewController(controller: self, frame: frame)
should be inviewDidLoad()
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:
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
)
-
MissingConfiguration
If we missing any parameter of
EkycConfig
, this error also notify theconfigurationName
to pointed out which param is missing
public func onLiveNessError(_ liveNessMatchError: LiveNessMatchError) {
switch liveNessMatchError {
...
case .MissingConfiguration(let config):
print(config)
}
- SSLPiningError
Trigger when SSLPining not passed
onLiveNessError(SSLPiningError)
- SecurityError
This error also include whichEKYCSecurityItem
not passed when do Security Check
onLiveNessError(SecurityError)
- TenanConfigError
Trigger when get tanant config failed
onLiveNessError(TenanConfigError)
- GetCredentialsError
Trigger when get credentials failed
onLiveNessError(GetCredentialsError)
- LivenessSetupError
Trigger when can't initialize liveness SDK
onLiveNessError(LivenessSetupError)
- CannotGetLiveNessToken
Trigger when get token liveness fail
onLiveNessError(CannotGetLiveNessToken)
- EkycMissing
Trigger when missing liveness from EKYC flow. Should be finish EKYC before do liveness match checker.
onLiveNessError(EkycMissing)
- 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:
APMSecurityItem | Description | Error Code | Sub Error Code |
---|---|---|---|
EMULATOR | This device is emulator | 1 | 0 |
JAILBROKEN | This device is jailbroken | 2 | 0 |
DEBUG | This device is attaching to debugger | 3 | 0 |
REVERSE_TOOLS | This device has evidence of reverse engineering | 4 | 0 |
PROXY | This device is acted as a proxy | 5 | 0 |
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>
ekycConfiguration.enableSecurityProtection = true
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:
Name | Version |
---|---|
CocoaLumberjack | 3.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
Updated 25 days ago