Skip to content

Usage Guide

Quick Start

Import the SDK and start the scanner with a result delegate:

swift
import UIKit
import KinegramScanSDK

class ViewController: UIViewController {
    let scanSdk = KSCScanSDK() 

    @IBAction func buttonStartScannerTouched(_ sender: UIButton) {
        scanSdk.startScanner(withDelegate: self, title: "ScanSDK Demo") 
    }
}

extension ViewController: KSCResultDelegate {
    func found(_ results: [KSCResult]) {
        for result in results {
            print("Scanned result: \(result)")
        }
    }
}

Processing Results

An array of KSCResult objects is returned by the delegate method. Each KSCResult contains the recognized data along with its type, defined by the KSCResultType enum:

swift
extension ExampleViewController: KSCResultDelegate {
    func found(_ results: [KSCResult]) {
        for result in results {
            switch result.type {
            case .MRZ:
                if let mrz = result.mrz {
                    print("MRZ found: \(result.text)")
                    print(" Document Code: \(mrz.documentCode)")
                    print(" Issuing State: \(mrz.issuingState)")
                    print(" Primary Identifier: \(mrz.primaryIdentifier)")
                    print(" Secondary Identifier: \(mrz.secondaryIdentifier)")
                    print(" Nationality: \(mrz.nationality)")
                    print(" Document Number: \(mrz.documentNumber)")
                    print(" Date of birth: \(mrz.dateOfBirth)")
                    print(" Sex: \(mrz.sex)")
                    print(" Date of expiry: \(mrz.dateOfExpiry)")
                    print(" Optional Data 1: \(mrz.optionalData1)")
                    print(" Optional Data 2: \(mrz.optionalData2)")
                    print(" Blank Number: \(mrz.blankNumber)")
                    print(" Language: \(mrz.language)")

                    // Handle MRZ validation errors (see MRZError enum)
                    for error in mrz.errors {
                        if let e = MRZError(rawValue: error.intValue) {
                            print(" Error: \(e)")
                        }
                    }
                }

            case .NumberPlate:
                if let numberPlate = result.numberPlate {
                    print("NumberPlate found: \(numberPlate.text)")
                    print(" First part: \(numberPlate.firstPart)")
                    print(" Second part: \(numberPlate.secondPart)")
                    print(" Country: \(numberPlate.country)")
                }

            case .IDL:
                if let idl = result.idl {
                    print("IIN found: \(idl.iin)")
                    for key in idl.order {
                        if let key = key as? String, let value = idl.elements[key] {
                            print("\(key): \(value)")
                        }
                    }
                }

            case .Barcode:
                print("Barcode format: \(result.format)")
                print("Barcode text: \(result.text)")

            case .IDB:
                if let idb = result.idb {
                    print("IDB found:")
                    print("Country ID: \(idb.header.countryId)")
                    // See class KSCIDBInfo for more information
                    print("Signature Valid: \(idb.signatureValid)")
                }

            case .VDS:
                if let vds = result.vds {
                    print("VDS found:")
                    print("Country ID: \(vds.header.countryId)")
                    // See class KSCVDSInfo for more information
                    print("Signature Valid: \(vds.signatureValid)")
                }

            case .VDSNC:
                if let vdsnc = result.vdsnc {
                    print("VDS-NC found:")
                    print("Country ID: \(vdsnc.header.issuingCountry)")
                    // See class KSCVDSNCInfo for more information
                    print("Signature Valid: \(vdsnc.signatureValid)")
                    print("Certificate Known: \(vdsnc.certificateKnown)")
                }

            default:
                print(result.text)
            }
        }
    }
}

MRZ Validation Errors

The mrz.errors property contains an array of NSNumber values representing validation errors found during MRZ parsing. Convert them to MRZError enum values for easier handling:

swift
for error in mrz.errors {
    if let e = MRZError(rawValue: error.intValue) {
        switch e {
        case .ErrorDocumentNumberCheckDigit:
            print("Document number check digit invalid")
        case .ErrorDateOfBirthCheckDigit:
            print("Date of birth check digit invalid")
        case .ErrorDateOfExpiryCheckDigit:
            print("Date of expiry check digit invalid")
        case .ErrorCombinedCheckDigit:
            print("Combined check digit invalid")
        // Handle other cases…
        default:
            break
        }
    }
}

See the MRZError enum in KSCMRZInfo.h for the complete list of error types.

Custom IDB Profiles

Use setIDBProfiles() to set custom IDB profiles before scanning:

swift
scanSdk.setIDBProfiles(
    "[{\"tag\":9,\"name\":\"Card Access Number\",\"type\":\"C40STR\"}]"
)

Custom VDS Profiles

Use setVDSProfiles() to specify custom VDS profiles:

swift
scanSdk.setVDSProfiles(
    "[{\"id\":4128,\"features\":[{\"tag\":2,\"name\":\"foo\",\"type\":\"UTF8STR\"}]}]"
)

The integer key (4128 in this example, which is 0x1020 hexadecimal; JSON does not support hexadecimal numbers) must be the "Document Feature Definition Reference" byte (0x10 in bit 9 to 16) and the "Document Type Category" byte (0x20 in bit 1 to 8). These bytes identify a VDS profile.

Document Feature Types

For each document feature you need to specify a tag, a name, and a type. Possible types are:

TypeDescription
RAWBinary data
UBYTEUnsigned char
UINT16LEUnsigned 16-bit integer little endian
UINT24LEUnsigned 24-bit integer little endian
UINT32LEUnsigned 32-bit integer little endian
DATEUnsigned 24-bit integer big endian read as "MMddyyyy"
TIMESTAMPUnix time stamp
UTF8STRUTF8 string
C40STRC40-encoded string
C40MRZMRVAC40-encoded MRVA MRZ
C40MRZMRVBC40-encoded MRVB MRZ
C40MRZTD2C40-encoded TD2 MRZ
C40MRZTD3C40-encoded TD3 MRZ

VDS Verification

To verify a VDS, you need the certificate with which the VDS was signed.

Use setCertificates() to specify a list of certificate files before scanning:

swift
scanSdk.setCertificates(["path/to/certificate.cer"])

VDS-NC / IDB Verification

To verify a VDS-NC or IDB barcode, the CSCA (Country Signing Certificate Authority) certificate of the issuing country is required. This certificate can be obtained from the ICAO master list or the BSI master list.

Use setCMS() to specify a list of master list files before scanning:

swift
scanSdk.setCMS(["path/to/masterlist.ml"])