DOT iOS NFC library

v7.4.0

Introduction

DOT iOS NFC provides a component for NFC reading which is easy to integrate into an iOS application. Supported documents are those which implement ICAO Doc 9303: Machine Readable Travel Documents as specified by International Civil Aviation Organization (ICAO).

Requirements

  • Xcode 14+

  • Framework supports iOS 13+. However, it can be added to projects with minimum deployment target iOS 11.0+. This allows you to put DOT iOS NFC code in @available block.

  • Swift or Objective-C

  • CocoaPods or Swift Package Manager

  • NFC reading capability is available on iPhone 7 and newer.

Distribution

Swift Package Manager

DOT iOS NFC is distributed as a binary XCFramework - DotNfc.xcframework with its dependencies stored in our public github repository. It can be easily integrated into Xcode project in: Project → Package Dependencies.

Use https://github.com/innovatrics/dot-ios-sdk-spm.git repository and choose the version you want to use. There you can select DotNfc package. All the required dependencies will be downloaded with the selected package.

Cocoapods

DOT iOS NFC is distributed as a XCFramework - DotNfc.xcframework using Cocoapods with its dependencies stored in our public github repository. It can be easily integrated into Xcode with custom definition of podspecs. First step is to insert following line of code on top of you Podfile.

Podfile
source 'https://github.com/innovatrics/innovatrics-podspecs'

Then DOT iOS NFC dependency must be specified in Podfile. Dependencies of DOT iOS NFC will be downloaded alongside it.

Podfile
source 'https://github.com/innovatrics/innovatrics-podspecs'

use_frameworks!

target 'YOUR_TARGET' do

pod 'dot-nfc'

end

In case of CocoaPods problem with pod install, try to clone the private pod repository manually.

pod repo remove innovatrics
pod repo add innovatrics https://github.com/innovatrics/innovatrics-podspecs

Supported Architectures

DOT iOS NFC provides all supported architectures in the distributed XCFramework package. Device binary contains: arm64. Simulator binary contains: x86_64, arm64.

Licensing

In order to use DotSdk in your iOS application, it must be licensed. The license can be compiled into the application as it is bound to Bundle Identifier specified in the General tab in Xcode.

The Bundle ID can be also retrieved in runtime by calling DotSdk.shared.bundleId.

In order to obtain the license, please contact your Innovatrics’ representative specifying Bundle ID. After you have obtained your license file, add it to your Xcode project and use it during the DotSdk initialization, as shown below.

Permissions

  • Add capability to your Xcode target: Near Field Communication Tag Reading

  • DOT iOS NFC requires following keys in Info.plist:

Info.plist
<key>NFCReaderUsageDescription</key>
<string>NFC tag to read NDEF messages into the application</string>

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

Transaction Reporting

DOT iOS NFC reports transactions to a remote service. Read more details in the Product Documentation.

Basic Setup

Initialization

Before using any of the components, you need to initialize DOT SDK with the license and DotNfcLibrary object.

DOT SDK Sample shows how to initialize DOT SDK with DotNfcLibrary. DotSdk.shared.initialize() method should be called on background thread.

Keep in mind that if you try to use any feature which was not added during initialization DOT SDK will generate fatal error.

Deinitialization

When you have finished using the DOT iOS NFC, it is usually a good practice to deinitialize it in order to free the memory. You can deinitialize DOT iOS NFC only after the complete process is finished and not within the life cycle of individual components. This can be performed using the DotSdk.shared.deinitialize() method. If you want to use the DOT iOS NFC components again, you need to call DotSdk.shared.initialize() again.

Logging

DOT iOS NFC supports logging using a global Logger class. You can set the log level as follows:

import DotNfc

Logger.logLevel = .debug

Log levels:

  • info

  • debug

  • warning

  • error

  • none

Each log message contains DotNfc tag. Keep in mind that logging should be used just for debugging purposes.

Components

Overview

DOT iOS NFC provides a non-UI component for NFC reading. You may customize native UI which is presented during the NFC reading on the iOS platform.

List of Non-UI Components

NFC TRAVEL DOCUMENT READER

The component for reading NFC enabled travel documents.

FLAT TAG STRUCTURE PARSER

The component for parsing flat tag structure in a data group as defined in Doc 9303.

Non-UI Components

NFC Travel Document Reader

The NfcTravelDocumentReader class provides NFC reading functionality.

Create NfcTravelDocumentReader:

let authorityCertificatesUrl = Bundle.main.url(forResource: "masterList", withExtension: "pem")
let configuration = NfcTravelDocumentReaderConfiguration(authorityCertificatesUrl: authorityCertificatesUrl)
let nfcTravelDocumentReader = NfcTravelDocumentReader(configuration: configuration)
nfcTravelDocumentReader.setDelegate(self)

To read NFC data, call the following method:

nfcTravelDocumentReader.read(nfcKey: nfcKey, activeAuthenticationChallenge: activeAuthenticationChallenge)

NfcKey is the access key to NFC data. ActiveAuthenticationChallenge is used in case, when server-side authentication of the chip is required. If the Active Authentication protocol is supported by the chip, it will be used for the authentication of the chip and the response (signature) will be returned in TravelDocument class.

You can handle the NfcTravelDocumentReader events using its delegate NfcTravelDocumentReaderDelegate.

@objc(DOTNfcTravelDocumentReaderDelegate) public protocol NfcTravelDocumentReaderDelegate {

    /// Tells the delegate that NFC reading has finished successfully with travel document as a result.
    @objc func nfcTravelDocumentReader(_ nfcTravelDocumentReader: NfcTravelDocumentReader, succeeded travelDocument: TravelDocument)

    /// Tells the delegate that NFC reading has failed with an error.
    @objc func nfcTravelDocumentReader(_ nfcTravelDocumentReader: NfcTravelDocumentReader, failed error: NfcTravelDocumentReaderError)
}

After the NFC reading session has started, there are three possible ways how the session can end:

  • NFC reading was successful - Dialog shows success animation and is dismissed afterwards.

  • NFC reading encountered an error - Dialog shows error animation and is dismissed afterwards.

  • NFC reading timed out (iOS CoreNFC has strict time out of 60 seconds for NFC reading session.) - Dialog is dismissed immediately.

NfcKey

The NfcKey object is created from the travel document number, date of birth and date of expiry.

let nfcKey = try NfcKey(documentNumber: documentNumber, dateOfExpiry: dateOfExpiry, dateOfBirth: dateOfBirth)

Flat Tag Structure Parser

The FlatTagStructureParser class parses input data into a dictionary of data elements.

Create a FlatTagStructureParser:

let flatTagStructureParser = FlatTagStructureParser()

To parse a Data Group value, call the following method:

let elements = try flatTagStructureParser.parse(value: bytes)

Following data structure is expected as an input:

ELEMENT_1_TAG, ELEMENT_1_LENGTH, ELEMENT_1_VALUE, ..., ELEMENT_N_TAG, ELEMENT_N_LENGTH, ELEMENT_N_VALUE

Such a value is parsed into this map:

Table 1. Map of Data Elements

Tag

Value

ELEMENT_1_TAG

ELEMENT_1_VALUE

…​

…​

ELEMENT_N_TAG

ELEMENT_N_VALUE

This is an example of a resulting map:

Table 2. Example of a map of Data Elements

Tag

Length

Value

0x5C

0x02

0x5F_5B

0x5F_5B

0x08

SPECIMEN (shown as text for readability)

Some country authorities may use this structure in the Optional Details. This data is present in TravelDocument.optionalDetails as a result of the NFC reading.

Customization of native UI

Localization

String resources can be overridden in your application and alternative strings for supported languages can be provided following these two steps:

  1. Add your own Localizable.strings file to your project using standard iOS localization mechanism. To change a specific text override corresponding key in this Localizable.strings file.

  2. Set the localization bundle to the bundle of your application (preferably during the application launch in your AppDelegate).

Use this setup if you want to use standard iOS localization mechanism, which means your iOS application uses system defined locale.

import DotNfc

Localization.bundle = .main
Custom Localization

You can override standard iOS localization mechanism by providing your own translation dictionary and setting the Localization.useLocalizationDictionary flag to true. Use this setup if you do not want to use standard iOS localization mechanism, which means your iOS application ignores system defined locale and uses its own custom locale.

import DotNfc

guard let localizableUrl = Bundle.main.url(forResource: "Localizable", withExtension: "strings", subdirectory: nil, localization: "de"),
      let dictionary = NSDictionary(contentsOf: localizableUrl) as? [String: String]
else { return }

Localization.useLocalizationDictionary = true
Localization.localizationDictionary = dictionary
Localizable.strings
"dot.nfc_travel_document_reader.instruction.beginReading" = "Slide your phone gently on the surface of the document until we find the right position.";
"dot.nfc_travel_document_reader.instruction.readingSuccessful" = "Scanning was successful.";

"dot.nfc_travel_document_reader.instruction.accessControlError" = "There was a problem establishing access control with the document.";
"dot.nfc_travel_document_reader.instruction.readingError" = "There was an error reading the document.";

"dot.nfc_travel_document_reader.instruction.readingInProgress" = "Hold still, we are working on it.";

"dot.nfc_travel_document_reader.progressSymbol.empty" = "\U25CB";
"dot.nfc_travel_document_reader.progressSymbol.full" = "\U25CF";

Appendix

Changelog

7.4.0 - 2024-03-19

Fixed
  • Chip Authentication for eMRTD documents with large public keys.

Added
  • Vibration feedback when a connection with an NFC chip has been established.

  • Localization key dot.nfc_travel_document_reader.instruction.readingInProgress for text instruction during the NFC reading process.

Changed
  • Text instruction for localization keys dot.nfc_travel_document_reader.instruction.beginReading, .readingSuccessful.

Removed
  • Localization keys dot.nfc_travel_document_reader.instruction.establishAccessControl, .readingCom, .readingSod, .readingDG[1-16], .readingUnknownDG.

7.3.0 - 2024-02-23

Fixed
  • Fixed licensing issue. Newly generated licenses will only work from this and subsequent releases.

Added
Changed
  • NfcTravelDocumentReaderDelegate is using NfcTravelDocumentReaderProtocol instead of NfcTravelDocumentReader.

  • Deprecated NfcTravelDocumentReader.init(), use NfcTravelDocumentReaderFactory.create() instead.

7.2.1 - 2024-01-11

  • Technical release. No changes.

7.2.0 - 2023-12-28

  • Technical release. No changes.

7.1.1 - 2023-12-21

  • Technical release. No changes.

7.1.0 - 2023-12-14

Changed
  • Access Control mechanism reworked. BAC protocol is used by default. PACE protocol is used only if BAC protocol fails or BAC is not available.

7.0.2 - 2023-12-04

Fixed
  • DOT SDK initialization (license parsing).

7.0.1 - 2023-12-01

Changed
  • Updated renamed DotOpenSSL dependency version to 1.2.0.

7.0.0 - 2023-11-02

Added
  • Class DotSdk.

  • Class DotSdkConfiguration.

  • Protocol DotLibrary.

  • License file is required. To obtain one, please contact support@innovatrics.com.

Changed
  • Class DotNfcLibrary reworked.

6.5.1 - 2023-10-19

Fixed
  • Unable to parse Document Signing Certificate of some documents.

  • NfcTravelDocumentReader.read() was creating strong reference cycle.

6.5.0 - 2023-10-04

  • Technical release. No changes.

6.4.0 - 2023-09-19

  • Technical release. No changes.

6.3.0 - 2023-08-18

  • Technical release. No changes.

6.2.0 - 2023-07-26

  • Technical release. No changes.

6.1.1 - 2023-07-19

Fixed
  • Handling of the case when travel document does not support Chip Authentication and Active Authentication.

6.1.0 - 2023-07-07

  • Technical release. No changes.

6.0.0 - 2023-06-14

  • Technical release. No changes.

5.5.0 - 2023-04-26

Added
  • explicit challenge-response for Active Authentication in API suitable for server-side validation.

  • activeAuthenticationChallenge argument to NfcTravelDocumentReader.read() method.

  • ChipAuthenticationStatus.activeAuthenticationResponse.

5.4.0 - 2023-03-24

  • Technical release. No changes.

5.3.0 - 2023-03-23

  • Technical release. No changes.

5.2.0 - 2023-03-06

Added
  • TravelDocument.authenticationStatus

  • AuthenticationStatus

  • ChipAuthenticationStatus

  • DataAuthenticationStatus

Removed
  • TravelDocument.activeAuthenticationStatus

  • TravelDocument.passiveAuthenticationStatus

5.1.1 - 2023-02-21

Added
  • support for Swift Package Manager.

5.1.0 - 2023-02-08

  • Technical release. No changes.

5.0.0 - 2023-01-27

Changed
  • New SDK versioning: All libraries (DOT Document, DOT Face, DOT Face Lite and DOT NFC) are released simultaneously with a single version name. Libraries with the same version name work correctly at build time and at run time.

Fixed
  • @objc prefix pattern to DOTN*

2.3.3 - 2022-12-02

Fixed
  • parsing of country code in TravelDocument.machineReadableZoneInformation.issuingStateOrOrganization and .nationality

2.3.2 - 2022-10-24

Fixed
  • NFC reading retry count was resetting improperly

Changed
  • minimal required version to Xcode 14+

2.3.1 - 2022-08-16

Fixed
  • stability of NFC reading session

  • improved user experience by adding progress bar

  • added localization keys for progress bar symbols

2.3.0 - 2022-07-21

Added
  • DotNfcLibrary.versionName

  • TravelDocument.ldsMasterFile

  • LdsMasterFile

  • Lds1eMrtdApplication

  • Lds1ElementaryFile

Fixed
  • TravelDocument.encodedIdentificationFeaturesFace to Non-Optional

2.2.3 - 2022-07-01

Fixed
  • support for Access Control Protocol - PACE - Integrated Mapping

  • parsing of NameOfHolder

2.2.2 - 2022-06-08

Fixed
  • support for Access Control Protocol - PACE

2.2.1 - 2022-04-22

Fixed
  • parsing of AdditionalPersonalDetails.otherNames

2.2.0 - 2022-01-21

Added
  • FlatTagStructureParser

2.1.0 - 2022-01-19

Added
  • OptionalDetails

  • TravelDocument.optionalDetails

Changed
  • AdditionalPersonalDetails.nameOfHolder type from String? to NameOfHolder?

Fixed
  • resolving of JPEG image format, using ImageFormat.jpeg

2.0.2 - 2021-12-13

Fixed
  • parsing of AdditionalDocumentDetails.dateOfIssue

2.0.1 - 2021-12-13

Fixed
  • wrong Passive Authentication flag returned

  • Image Objective-C class name changed from DOTImage to DOTNImage

2.0.0 - 2021-12-02

Added
  • NfcKey

  • NfcTravelDocumentReaderConfiguration

  • NfcTravelDocumentReaderDelegate

  • NfcTravelDocumentReaderError

  • PassiveAuthenticationStatus

  • ActiveAuthenticationStatus

  • Image

  • MachineReadableZoneInformation

  • EncodedIdentificationFeaturesFace

  • DisplayedSignatureOrUsualMark

  • AdditionalPersonalDetails

  • AdditionalDocumentDetails

  • NameOfHolder

  • AccessControlProtocol

  • Logger

Changed
  • minimal required iOS version to iOS 11.0

  • added support for simulator build

  • added support for bitcode, ENABLE_BITCODE = YES

  • updated OpenSSL to version 1.1.1l

  • added support for Active Authentication with RSA public keys

  • removed default master list

  • renamed module to DotNfc

  • renamed DotNfcLocalization to Localization

  • updated localization keys

  • renamed NFCPassportReader to NfcTravelDocumentReader

  • NfcTravelDocumentReader is now using delegate pattern

  • changed NFCPassportReader.readPassport(mrzKey: String, result: @escaping ReadPassportResult) → Void to NfcTravelDocumentReader.read(nfcKey: NfcKey)

  • renamed Passport to TravelDocument

Removed
  • NFCFormatter

1.2.1 - 2021-10-01

Changed
  • release library as a XCFramework package

1.2.0 - 2021-03-04

Added
  • DotNfcLocalization class to enable localization of alert messages

1.1.1 - 2020-10-23

Fixed
  • removed force unwraps and added better error handling

1.1.0 - 2020-07-30

Added
  • Released as a new component dot-nfc

1.0.3 - 2020-03-31

Changed
  • Renamed class NFCReader to NFCPassportReader

1.0.2 - 2020-03-31

Added
  • BUILD_LIBRARY_FOR_DISTRIBUTION = YES

1.0.1 - 2020-03-12

Added
  • OpenSSL dependancy as an external pod dependancy innovatrics-openssl

1.0.0 - 2020-03-02

Added
  • faceImage and signatureImage to Passport struct