4️⃣ Scan Document
Last updated
Was this helpful?
Last updated
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.
The scanDocument
API will compute the bac key from the MRZ and return an EDocument
if the entire flow is successful.
fun scanDocument(onCompletion: (DocumentResult<EDocument>) -> Unit)
public static func scanDocument(
completion: @escaping (Result<EDocument, DocumentError>) -> Void
)
Future<DocumentResult<EDocument>> scanDocument();
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;
}
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;
KeylessDocument.scanDocument() {
when (it) {
is DocumentResult.Success -> {
Log.d(TAG, "EDocument ${it.value}")
}
is DocumentResult.Failure -> {
Log.d(TAG, "Error ${it.error}")
}
}
KeylessDocument.scanDocument() { result in
switch result {
case .success(let document):
print("EDocument: \(document)")
case .failure(let error):
print("Error: \(error)")
}
}
DocumentResult<EDocument> documentResult = await KeylessDocument.instance.scanDocument();
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;