KINEGRAM eMRTD SDK iOS

iOS SDK for reading and verifying electronic Machine Readable Travel Documents (eMRTD) locally on-device.

┏━━━━━━━━━━━━━━━━━━━━━━━━┓
┃                        ┃
┃  KinegramEmrtd SDK     ┃
┃                        ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━┛
        ▲
        │ NFC
        ▼
┌──────────────┐
│              │
│   PASSPORT   │
│              │
│   ID CARD    │
│              │
│              │
│   (eMRTD)    │
│              │
└──────────────┘

The KINEGRAM eMRTD SDK reads and verifies electronic passports and ID cards in accordance with ICAO Doc 9303. All processing happens locally on the device - no server connection required.

Features

Installation

Add the following to your Package.swift:

dependencies: [
    .package(url: "https://github.com/OVD-Kinegram-AG/emrtd-sdk-ios", from: "2.13.2")
]

Or in Xcode: File -> Packages -> Add Package Dependency... and enter:

https://github.com/OVD-Kinegram-AG/emrtd-sdk-ios

CocoaPods

Add the following to your Podfile:

pod 'KinegramEmrtd', '~> 2.13.2'

Then run pod install.

Note: CocoaPods support is provided for compatibility with existing projects. We recommend Swift Package Manager as CocoaPods is only in maintenance mode since September 2024 (official announcement).

Quick Start

import KinegramEmrtd

// Initialize EmrtdReader
let emrtdReader = EmrtdReader()

// Load Master List (CSCA certificates for Passive Authentication)
let masterListURL = Bundle.main.url(forResource: "masterlist", withExtension: "ml")!
try emrtdReader.readMasterlist(from: masterListURL)

// Read and verify passport
let mrzKey = MRZKey(
    documentNumber: "123456789",
    birthDateyyMMdd: "970101",
    expiryDateyyMMdd: "251212"
)

do {
    let result = try await emrtdReader.readAndVerify(accessKey: mrzKey)

    // Access MRZ info
    if let dg1 = result.dg1File {
        print("Document Number: \(dg1.documentNumber)")
        print("Name: \(dg1.primaryIdentifier) \(dg1.secondaryIdentifier)")
    }

    // Access face photo
    if let faceInfo = result.dg2File?.faceInfos?.first {
        let faceImage: UIImage? = faceInfo.uiImage
    }

    // Check verification results
    print("Passive Authentication: \(result.passiveAuthenticationResult)")
    print("Active Authentication: \(result.activeAuthenticationResult)")
    print("Chip Authentication: \(result.chipAuthenticationResult)")
} catch {
    print("Error reading passport: \(error)")
}

Reading PACE-enabled Documents

Some identity documents require PACE polling to be detected (requires iOS 16+):

let canKey = CANKey(can: "123456")
do {
    let result = try await emrtdReader.readAndVerify(
        accessKey: canKey,
        usePACEPolling: true
    )
} catch EmrtdReaderError.PACEPollingNotAvailable {
    print("PACE polling requires iOS 16 or later")
} catch {
    print("Error: \(error)")
}

Important: PACE polling cannot detect standard passports - use it only when the document requires it.

Documentation

Full API documentation is available here

Example App

Check out the Example directory for a complete SwiftUI app demonstrating: - MRZ input and validation - NFC passport reading with progress - Verification result display (PA, AA, CA)

Error Handling

do {
    let result = try await emrtdReader.readAndVerify(accessKey: mrzKey)
} catch EmrtdReaderError.accessControlFailed {
    print("Wrong MRZ data - check document number, birth date, and expiry date")
} catch EmrtdReaderError.PACEPollingNotAvailable {
    print("PACE polling requires iOS 16+")
} catch EmrtdReaderError.nfcNotAvailable(let reason) {
    print("NFC not available: \(reason)")
} catch {
    print("Error: \(error)")
}

Requirements Setup

1. Enable NFC Capability

Enable Near Field Communication Tag Reading in the target Signing & Capabilities.

The *.entitlements file needs:

<dict>
    <key>com.apple.developer.nfc.readersession.formats</key>
    <array>
        <string>PACE</string>
        <string>TAG</string>
    </array>
</dict>

2. Info.plist

Add the AID list and NFC usage description:

<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
<array>
    <string>A0000002471001</string>
    <string>A0000002472001</string>
</array>

<key>NFCReaderUsageDescription</key>
<string>This app uses NFC to verify passports</string>

Changelog

Changelog

Credits