OVD KINEGRAM ScanSDK for iOS

OVD KINEGRAM ScanSDK is a powerful SDK that enables developers to integrate scanning functionalities into their iOS applications.

The SDK supports the scanning of various objects, such as

Supported Number Plates

ScanSDK has been trained to recognize license plates from Switzerland, UK, and the EU in accordance with EU Council Regulation (EC) No 2411/98.

Supported Barcode Formats

Linear product Linear industrial Matrix
UPC-A Code 39 QR Code
UPC-E Code 93 Micro QR Code
EAN-8 Code 128 rMQR Code
EAN-13 Codabar Aztec
DataBar DataBar Expanded DataMatrix
DX Film Edge PDF417
ITF MaxiCode (partial)

Preconditions

Example App

The folder Example contains a minimal functional demo app, that shows the usage of the SDK. Remember to set your Team in the Signing & Capabilities settings for the Target Example in this project, when building for an iOS device.

Framework Installation

Swift Package Manager

To add OVD KINEGRAM ScanSDK to your Xcode project using Swift Package Manager:

  1. Open your project in Xcode.
  2. Navigate to File > Add Package Dependencies.
  3. Enter the repository URL: https://github.com/OVD-Kinegram-AG/scan-sdk-ios and add the package.

Usage

Importing

Import the SDK in the file where you want to use it:

import KinegramScanSDK

Quick Start

Here is a simple example of how to use the scanner in your application:

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]) {
        // Process results
        for result in results {
            print("Scanned result: \(result)")
        }
    }
}

Possible Return Values

KSCResult

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

Handling Results

When using the KSCScanSDK, the results of the scan are returned through the KSCResultDelegate. Here is an example of how to handle different types of scan results:

...
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)")
                }

            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 .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)
            }
        }
    }
}

Additional Hints

1. NSCameraUsageDescription in Host App

As the OVD KINEGRAM ScanSDK needs camera access, the host app has to put a usage description inside its Info.plist, otherwise the app crashes. Please add a string like this to the Info.plist of the host app:

<key>NSCameraUsageDescription</key>
<string>$(PRODUCT_NAME) needs camera access to scan your documents.</string>

Custom VDS Profiles

Use Scanner.setVDSProfiles() to specify custom VDS profiles before scanning:

Scanner.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, unfortunately) 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.

For each document feature you need to specify a tag (2), a name (foo) and a type (UTF8STR). Possible types are:

Verify a VDS

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

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

Scanner.setCertificates(listOf("path/to/certificate.cer"))

Verify a VDS-NC

To verify a VDS-NC 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 Scanner.setCMS() to specify a list of master list files before scanning:

Scanner.setCMS(listOf("path/to/masterlist.ml"))

Changelog

Changelog

License

LICENSE

Support

If you encounter any issues or have any questions, we encourage you to open an issue in the GitHub issue tracker.

Our team will be happy to assist you and address any problems you may have. Alternatively, you can contact us at .