This repository builds and packages two SDKs:
KinegramEmrtd.xcframework (Core, offline): read and
verify an eMRTD locally in accordance with ICAO
Doc 9303.KinegramEmrtdConnector.xcframework (Connector, online):
connect to the DocVal server over WebSocket v2.Important notes: - Core and Connector are separate products — do not
embed both in the same app. - The Connector is an all‑in‑one build (Core
+ Connector sources compiled into a single module) but is distributed as
a binary‑only package in the separate
emrtd-connector-sdk-ios repository (in OVDK’s GitHub). -
JPEG2000 (JP2): Core optionally includes OpenJPEG (controlled via
-DWITH_OPENJPEG). The Connector does not include JP2
decoding.
The Xcode Project KinegramEmrtdExample.xcodeproj
contains a minimal fully functional demo app, that shows the usage of
the SDK. Remember to set your Team in the
Signing & Capabilities settings for the Target
KinegramEmrtdExample in this project.
Set your Team in the Signing & Capabilities settings for all Targets in this project.
Select the scheme ExampleApp and click Run.
There are different ways to add
KinegramEmrtd.xcframework to your project:
Put the xcframework files into your target’s
dependencies. (Project settings –> General –> Frameworks,
Libraries, and Embedded Content)
In your Xcode project, go to
File -> Packages -> Add Package Dependency... and
enter the URL of this repository or the path to the local folder.
There is a prepared KinegramEmrtd.podspec.
If you already use Cocoapods for dependency management, you can simply add the frameworks with one statement in your Podfile:
platform :ios, '13.0'
target 'emrtd-sdk-sample' do
use_frameworks!
# local Pod
pod 'KinegramEmrtd', :path => 'SDK/'
# ... could be also managed your own git
#pod 'KinegramEmrtd', :git => 'https://git.yourdomain.com/.git'
end
Then, run pod install command to integrate the SDK into
your project.
AIDs it can connect
to, in the Info.plist file.The AID is a way of uniquely identifying an application
on a ISO 7816 tag. eMRTDS use the AID A0000002471001. Your
Info.plist entry should look like this:
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
<string>A0000002471001</string>
<string>A0000002472001</string>
</array>NFCReaderUsageDescription
key: <key>NFCReaderUsageDescription</key>
<string>This app uses NFC to verify passports</string>This new entitlement is added automatically by Xcode when enabling the Near Field Communication Tag Reading capability in the target Signing & Capabilities.
After enabling the capability the *.entitelments file needs to
contain the TAG format:
...
<dict>
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
<string>PACE</string> // Needed for PACE polling support (some ID cards)
<string>TAG</string> // Application specific tag, including ISO 7816 Tags
</array>
</dict>
...View the Core DocC
documentation (GitLab Pages) or open the .doccarchive
locally in Xcode. For the Connector, HTML docs are published via GitHub
Pages in the distribution repository.
You can access the documentation from within Xcode by either hitting
Shift + Cmd + 0 or through
Window -> Developer Documentation.
import KinegramEmrtd
// Initialize EmrtdReader
let emrtdReader = EmrtdReader()
// Load Master List
let masterListURL = Bundle.main.url(forResource: "masterlist", withExtension: "ml")!
try emrtdReader.readMasterlist(from: masterListURL)
// Read and verify passport using async/await
let mrzKey = MRZKey(documentNumber: "123456789", birthDateyyMMdd: "970101", expiryDateyyMMdd: "211212")
do {
let emrtdResult = try await emrtdReader.readAndVerify(accessKey: mrzKey)
// Access MRZ info
if let dg1File = emrtdResult.dg1File {
print("Document Number: \(dg1File.documentNumber)")
}
// Access face photo
if let faceInfo = emrtdResult.dg2File?.faceInfos?.first {
let faceImage: UIImage? = faceInfo.uiImage
}
// Check verification results
print("Passive Authentication: \(emrtdResult.passiveAuthenticationResult)")
print("Active Authentication: \(emrtdResult.activeAuthenticationResult)")
print("Chip Authentication: \(emrtdResult.chipAuthenticationResult)")
} catch {
// Handle EmrtdReaderError
print("Error reading passport: \(error)")
}Some identity documents require PACE (Password Authenticated Connection Establishment) polling to be detected. This includes:
To read these documents, use the usePACEPolling
parameter (requires iOS 16+):
// Enable PACE polling for French ID cards and other PACE-enabled documents
let canKey = CANKey(can: "123456")
do {
let emrtdResult = try await emrtdReader.readAndVerify(accessKey: canKey, usePACEPolling: true)
// Process result...
} catch EmrtdReaderError.PACEPollingNotAvailable {
print("PACE polling requires iOS 16 or later")
} catch {
print("Error reading document: \(error)")
}Important Notes: - PACE polling is only available on
iOS 16 and later - PACE polling cannot detect standard passports - use
it only when you know the document requires it - The SDK will throw a
PACEPollingNotAvailable error if you try to use PACE
polling on iOS 15 or earlier