Documentation Hub
Mobile Document SDK
Mobile Document SDK
  • Mobile Document SDK
  • Introduction
    • Overview
  • 🪪Mobile Document SDK Guide
    • 1️⃣ Getting started
    • 2️⃣ Read MRZ
    • 3️⃣ Read NFC
    • 4️⃣ Scan Document
  • 🪪Mobile Document SDK Use Cases
    • Enroll from the document photo
Powered by GitBook
On this page
  • Api Signature
  • Returned result
  • Errors
  • Example usage

Was this helpful?

  1. Mobile Document SDK Guide

3️⃣ Read NFC

Last updated 5 days ago

Was this helpful?

To scan the NFC you need to provide the Basic Access Control - BAC - key. The BAC key is computed from the Machine Readable Zone - MRZ and acts as "" to access the chip content.

Api Signature

fun readNfcDocumentData(
    bacKey: BacKey,
    onCompletion: (DocumentResult<EDocument>) -> Unit,
)
public static func readDocumentNfcChip(
    bacKey: BacKey,
    completion: @escaping (Result<EDocument, DocumentError>) -> Void
)
Future<DocumentResult<EDocument>> readNfcDocumentData(BacKey bacKey) 

Returned result

If the Keyless Document SDK can read the NFC tag it will return an instance of EDocument containing the data read.

public data class EDocument(
	// The path to the image extracted from the document
    var facePath: String = UNKNOWN,
    // Personal information of the document holder
    var personalInformation: PersonalInformation = PersonalInformation(),
    // Information about the document itself    
    var documentInformation: DocumentInformation = DocumentInformation(),
    // Security-related information and verification status
    var security: DocumentSecurity = DocumentSecurity(),
)
public struct EDocument {
    /// The image extracted from the document
    public let passportImage: UIImage?
    /// Personal information of the document holder
    public let personalInformation: PersonalInformation
    /// Information about the document itself
    public let documentInformation: DocumentInformation
    /// Security-related information and verification status
    public let security: DocumentSecurity
class EDocument {
	// The path to the image extracted from the document
  	String facePath;
    // Personal information of the document holder
  	PersonalInformation personalInformation;
    // Information about the document itself      	
  	DocumentInformation documentInformation;
    // Security-related information and verification status  	
  	DocumentSecurity security;
}

Errors

In case of errors the Keyless Document SDK will return the following errors:

public sealed class DocumentError(
    public open val code: Int,
    public open val message: String,
) 

// errors launching the MrzCameraActivity
public data class InternalError(override val code: Int) : DocumentError(code, "Internal error")

public data object UserCancelled : DocumentError(
	code = 5000,
    message = "User cancelled the operation."
)

public data object LauncherNotInitialized : DocumentError(
    code = 5002,
    message = "Launcher is null or not initialized"
)

public data class ChipAuthError(val  errorMessage: String?  = null) : DocumentError(
    code = 7002,
    message =  errorMessage ?: "BAC Authentication failed"
)

public data class ChipException(val e: Throwable?) : DocumentError(
    code = 7003,
    message =  e?.message ?: "Chip exception"
)

public data class ChipLost(val permissionDenial: Boolean = false) : DocumentError(
    code = 7004,
    message = "Chip lost"
)

public data class UnknownError( override val message: String) : DocumentError(
    code = 9999,
    message = message
)
public enum DocumentError: Error {

        case userCancelled
        case chipAuthError(message: String)
        case chipException(underlyingError: Error?)
        case invalidDocument
        case unknownError(message: String)

       public var code: Int {
            switch self {
                case .userCancelled: return 5000
                case .invalidDocument: return 6003
                case .chipAuthError: return 7002
                case .chipException: return 7003
                case .unknownError: return 9999
            }
        }

        public var message: String {
            switch self {
                case .userCancelled: return "User cancelled the operation"
                case .chipAuthError(let message): return message
                case .chipException(let underlyingError): 
                	guard let ke = underlyingError as? DocumentError else {
                        return underlyingError?.localizedDescription ?? "Chip exception"
                    }
                    return ke.message
                case .invalidDocument: return "Invalid document format"
                case .unknownError(let message): return message
            }
        }
}
enum DocumentError {
  internalError,
  userCancelled,
  launcherNotInitialized,
  chipAuthError,
  chipException,
  chipLost,
  invalidDocument,
  unknownError;

Example usage

KeylessDocument.readNfcDocumentData(bacKey =  mrz.toBac()) {
    when (it) {
        is DocumentResult.Success -> {
            Log.d(TAG, "EDocument ${it.value}")
 		}
    	is DocumentResult.Failure -> {
            Log.d(TAG, "Error ${it.error}")
        }
}
KeylessDocument.readDocumentNfcChip(bacKey: mrz.toBac()) { result in
    switch result {
    case .success(let document):
        print("EDocument: \(document)")
    case .failure(let error):
        print("Error: \(error)")
    }
}
DocumentResult<EDocument> documentResult = await KeylessDocument.instance.readNfcDocumentData(bacKey);

switch (documentResult) {
    case DocumentSuccess<EDocument>(data: final document):
        String docRead = 'Document: ${document.facePath}, ...';
        break;
    case DocumentFailure(message: final error, code: final code, errorType: final type):
        String error = 'Document Error: $error $code ($type)';
        break;
🪪
proof of authorization