Skip to content

Commit a0c899a

Browse files
authored
feat: add custom labels text support to scan nfc process (#7)
* feat: add custom labels text support to scan nfc process * feat: add custom labels text support to scan nfc process * feat: add custom labels text support to scan nfc process
1 parent 8eaada9 commit a0c899a

9 files changed

Lines changed: 79 additions & 66 deletions

File tree

android/src/main/java/io/twentysixty/rn/eidreader/EIdReaderModule.kt

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class EIdReaderModule(reactContext: ReactApplicationContext) :
5757
private val jsonToReactMap = JsonToReactMap()
5858
private var _promise: Promise? = null
5959
private var _dialog: AlertDialog? = null
60+
private var labels: ReadableMap? = null
6061

6162
init {
6263
reactApplicationContext.addLifecycleEventListener(this)
@@ -171,7 +172,8 @@ class EIdReaderModule(reactContext: ReactApplicationContext) :
171172
)
172173

173174
currentActivity?.runOnUiThread(Runnable {
174-
_dialog?.setMessage("Reading. Hold your document...")
175+
val message = labels?.getString("reading") ?: "Reading. Hold your document..."
176+
_dialog?.setMessage(message)
175177
})
176178

177179
val result = nfcPassportReader.readPassport(IsoDep.get(tag), bacKey, includeImages, includeRawData)
@@ -199,7 +201,8 @@ class EIdReaderModule(reactContext: ReactApplicationContext) :
199201

200202
private fun reject(e: Exception) {
201203
currentActivity?.runOnUiThread(Runnable {
202-
_dialog?.setMessage("Sorry, there was a problem reading the passport. Please try again")
204+
val message = labels?.getString("error") ?: "Sorry, there was a problem reading the passport. Please try again"
205+
_dialog?.setMessage(message)
203206
})
204207
stopReading(false)
205208
_promise?.reject(e)
@@ -210,6 +213,7 @@ class EIdReaderModule(reactContext: ReactApplicationContext) :
210213
readableMap?.let {
211214
try {
212215
_promise = promise
216+
labels = readableMap?.getMap("labels")
213217
val mrzMap = readableMap?.getMap("mrzInfo")
214218
val mrzExpirationDate = mrzMap?.getString("expirationDate")
215219
val mrzBirthDate = mrzMap?.getString("birthDate")
@@ -230,11 +234,14 @@ class EIdReaderModule(reactContext: ReactApplicationContext) :
230234
val currentActivity = currentActivity
231235
if (currentActivity != null) {
232236
currentActivity?.runOnUiThread(Runnable {
237+
val title = labels?.getString("title") ?: "Ready to Scan"
238+
val message = labels?.getString("requestPresentPassport") ?: "Hold your phone near an NFC enabled passport"
239+
val cancelButton = labels?.getString("cancelButton") ?: "Cancel"
233240
val builder = AlertDialog.Builder(currentActivity)
234-
builder.setTitle("Ready to Scan")
235-
.setMessage("Hold your phone near an NFC enabled passport")
241+
builder.setTitle(title)
242+
.setMessage(message)
236243
.setCancelable(true)
237-
.setNegativeButton("Cancel") { dialog, _ ->
244+
.setNegativeButton(cancelButton) { dialog, _ ->
238245
stopReading()
239246
val reactMap = jsonToReactMap.convertJsonToMap(JSONObject("{status: 'Canceled' }"))
240247

ios/EidReader.swift

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class EIdReader: RCTEventEmitter {
3131
// TODO
3232
isReading = true
3333

34+
let labels = params["labels"] as? NSDictionary
3435
let mrzInfo = params["mrzInfo"] as! NSDictionary
3536
let expirationDate = mrzInfo["expirationDate"] as! String
3637
let birthDate = mrzInfo["birthDate"] as! String
@@ -44,16 +45,7 @@ class EIdReader: RCTEventEmitter {
4445
Task {
4546
var eidReadResult: [String: Any] = [:]
4647
do {
47-
let customMessageHandler : (NFCViewDisplayMessage)->String? = { (displayMessage) in
48-
switch displayMessage {
49-
case .requestPresentPassport:
50-
return "Hold your iPhone near an NFC enabled passport."
51-
default:
52-
// Return nil for all other messages so we use the provided default
53-
return nil
54-
}
55-
}
56-
let passport = try await passportReader.readPassport( mrzKey: mrzKey, useExtendedMode: false, customDisplayMessage:customMessageHandler)
48+
let passport = try await passportReader.readPassport( mrzKey: mrzKey, useExtendedMode: false, labels: labels)
5749

5850
var data: [String: Any] = [:]
5951

ios/NFCPassportReader/BACHandler.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public class BACHandler {
5656
let maResponse = try await tagReader.doMutualAuthentication(cmdData: Data(cmd_data))
5757
Logger.bac.debug( "DATA - \(maResponse.data)" )
5858
guard maResponse.data.count > 0 else {
59-
throw NFCPassportReaderError.InvalidMRZKey
59+
throw NFCPassportReaderError.InvalidMRZKey()
6060
}
6161

6262
let (KSenc, KSmac, ssc) = try self.sessionKeys(data: [UInt8](maResponse.data))

ios/NFCPassportReader/DataGroups/DataGroup.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public class DataGroup {
3737

3838
// Fix for some passports that may have invalid data - ensure that we do have data!
3939
guard data.count > pos else {
40-
throw NFCPassportReaderError.TagNotValid
40+
throw NFCPassportReaderError.TagNotValid()
4141
}
4242

4343
if binToHex(data[pos]) & 0x0F == 0x0F {

ios/NFCPassportReader/Errors.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,11 @@ public enum NFCPassportReaderError: Error {
2828
case UnknownTag
2929
case UnknownImageFormat
3030
case NotImplemented
31-
case TagNotValid
32-
case ConnectionError
31+
case TagNotValid(String? = nil)
32+
case ConnectionError(String? = nil)
3333
case UserCanceled
34-
case InvalidMRZKey
35-
case MoreThanOneTagFound
34+
case InvalidMRZKey(String? = nil)
35+
case MoreThanOneTagFound(String? = nil)
3636
case InvalidHashAlgorithmSpecified
3737
case UnsupportedCipherAlgorithm
3838
case UnsupportedMappingType

ios/NFCPassportReader/NFCViewDisplayMessage.swift

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,45 +9,46 @@ import Foundation
99

1010
@available(iOS 13, macOS 10.15, *)
1111
public enum NFCViewDisplayMessage {
12-
case requestPresentPassport
13-
case authenticatingWithPassport(Int)
14-
case readingDataGroupProgress(DataGroupId, Int)
15-
case error(NFCPassportReaderError)
16-
case activeAuthentication
17-
case successfulRead
12+
case requestPresentPassport(String? = nil)
13+
case authenticatingWithPassport(Int, String? = nil)
14+
case readingDataGroupProgress(DataGroupId, Int, String? = nil)
15+
case error(NFCPassportReaderError, String? = nil)
16+
case activeAuthentication(String? = nil)
17+
case successfulRead(String? = nil)
1818
}
1919

2020
@available(iOS 13, macOS 10.15, *)
2121
extension NFCViewDisplayMessage {
2222
public var description: String {
2323
switch self {
24-
case .requestPresentPassport:
25-
return "Hold your iPhone near an NFC enabled passport."
26-
case .authenticatingWithPassport(let progress):
24+
case .requestPresentPassport(let label):
25+
return label ?? "Hold your iPhone near an NFC enabled passport."
26+
case .authenticatingWithPassport(let progress, let label):
2727
let progressString = handleProgress(percentualProgress: progress)
28-
return "Authenticating with passport.....\n\n\(progressString)"
29-
case .readingDataGroupProgress(let dataGroup, let progress):
28+
let message = "\(label ?? "Authenticating with passport...")\n\n\(progressString)"
29+
return message
30+
case .readingDataGroupProgress(let dataGroup, let progress, let label):
3031
let progressString = handleProgress(percentualProgress: progress)
31-
return "Reading \(dataGroup).....\n\n\(progressString)"
32-
case .error(let tagError):
32+
return "\(label ?? "Reading...") \(dataGroup)n\n\(progressString)"
33+
case .error(let tagError, let label):
3334
switch tagError {
34-
case NFCPassportReaderError.TagNotValid:
35-
return "Tag not valid."
36-
case NFCPassportReaderError.MoreThanOneTagFound:
37-
return "More than 1 tags was found. Please present only 1 tag."
38-
case NFCPassportReaderError.ConnectionError:
39-
return "Connection error. Please try again."
40-
case NFCPassportReaderError.InvalidMRZKey:
35+
case NFCPassportReaderError.TagNotValid(let label):
36+
return label ?? "Tag not valid."
37+
case NFCPassportReaderError.MoreThanOneTagFound(let label):
38+
return label ?? "More than 1 tags was found. Please present only 1 tag."
39+
case NFCPassportReaderError.ConnectionError(let label):
40+
return label ?? "Connection error. Please try again."
41+
case NFCPassportReaderError.InvalidMRZKey(let label):
4142
return "MRZ Key not valid for this document."
4243
case NFCPassportReaderError.ResponseError(let description, let sw1, let sw2):
43-
return "Sorry, there was a problem reading the passport. \(description) - (0x\(sw1), 0x\(sw2)"
44+
return "\(label ?? "Sorry, there was a problem reading the passport. Please try again.") \(description) - (0x\(sw1), 0x\(sw2)"
4445
default:
45-
return "Sorry, there was a problem reading the passport. Please try again"
46+
return label ?? "Sorry, there was a problem reading the passport. Please try again"
4647
}
47-
case .activeAuthentication:
48-
return "Authenticating....."
49-
case .successfulRead:
50-
return "Passport read successfully"
48+
case .activeAuthentication(let label):
49+
return label ?? "Authenticating..."
50+
case .successfulRead(let label):
51+
return label ?? "Passport read successfully"
5152
}
5253
}
5354

ios/NFCPassportReader/PassportReader.swift

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import CoreNFC
1515

1616
@available(iOS 15, *)
1717
public class PassportReader : NSObject {
18+
private var labels: NSDictionary? = nil
1819
private var pendingPassportModel: NFCPassportModel? = nil
1920
private typealias NFCCheckedContinuation = CheckedContinuation<NFCPassportModel, Error>
2021
private var nfcContinuation: NFCCheckedContinuation?
@@ -64,8 +65,8 @@ public class PassportReader : NSObject {
6465
dataAmountToReadOverride = amount
6566
}
6667

67-
public func readPassport( mrzKey : String, tags : [DataGroupId] = [], skipSecureElements : Bool = true, skipCA : Bool = false, skipPACE : Bool = false, useExtendedMode : Bool = false, customDisplayMessage : ((NFCViewDisplayMessage) -> String?)? = nil) async throws -> NFCPassportModel {
68-
68+
public func readPassport( mrzKey : String, tags : [DataGroupId] = [], skipSecureElements : Bool = true, skipCA : Bool = false, skipPACE : Bool = false, useExtendedMode : Bool = false, customDisplayMessage : ((NFCViewDisplayMessage) -> String?)? = nil, labels: NSDictionary?) async throws -> NFCPassportModel {
69+
self.labels = labels
6970
self.passport = NFCPassportModel()
7071
self.mrzKey = mrzKey
7172
self.skipCA = skipCA
@@ -98,7 +99,7 @@ public class PassportReader : NSObject {
9899
if NFCTagReaderSession.readingAvailable {
99100
readerSession = NFCTagReaderSession(pollingOption: [.iso14443], delegate: self, queue: nil)
100101

101-
self.updateReaderSessionMessage( alertMessage: NFCViewDisplayMessage.requestPresentPassport )
102+
self.updateReaderSessionMessage( alertMessage: NFCViewDisplayMessage.requestPresentPassport(labels?["requestPresentPassport"] as? String))
102103
readerSession?.begin()
103104
}
104105

@@ -171,8 +172,8 @@ extension PassportReader : NFCTagReaderSessionDelegate {
171172
if tags.count > 1 {
172173
Logger.passportReader.debug( "tagReaderSession:more than 1 tag detected! - \(tags)" )
173174

174-
let errorMessage = NFCViewDisplayMessage.error(.MoreThanOneTagFound)
175-
self.invalidateSession(errorMessage: errorMessage, error: NFCPassportReaderError.MoreThanOneTagFound)
175+
let errorMessage = NFCViewDisplayMessage.error(NFCPassportReaderError.MoreThanOneTagFound(self.labels?["moreThanOneTagFound"]as? String))
176+
self.invalidateSession(errorMessage: errorMessage, error: NFCPassportReaderError.MoreThanOneTagFound(self.labels?["moreThanOneTagFound"] as? String))
176177
return
177178
}
178179

@@ -183,9 +184,8 @@ extension PassportReader : NFCTagReaderSessionDelegate {
183184
passportTag = tag
184185
default:
185186
Logger.passportReader.debug( "tagReaderSession:invalid tag detected!!!" )
186-
187-
let errorMessage = NFCViewDisplayMessage.error(NFCPassportReaderError.TagNotValid)
188-
self.invalidateSession(errorMessage:errorMessage, error: NFCPassportReaderError.TagNotValid)
187+
let errorMessage = NFCViewDisplayMessage.error(NFCPassportReaderError.TagNotValid(self.labels?["tagNotValid"] as? String))
188+
self.invalidateSession(errorMessage:errorMessage, error: NFCPassportReaderError.TagNotValid(self.labels?["tagNotValid"] as? String))
189189
return
190190
}
191191

@@ -194,7 +194,7 @@ extension PassportReader : NFCTagReaderSessionDelegate {
194194
try await session.connect(to: tag)
195195

196196
Logger.passportReader.debug( "tagReaderSession:connected to tag - starting authentication" )
197-
self.updateReaderSessionMessage( alertMessage: NFCViewDisplayMessage.authenticatingWithPassport(0) )
197+
self.updateReaderSessionMessage( alertMessage: NFCViewDisplayMessage.authenticatingWithPassport(0, self.labels?["authenticatingWithPassport"] as? String) )
198198

199199
let tagReader = TagReader(tag:passportTag)
200200

@@ -204,20 +204,20 @@ extension PassportReader : NFCTagReaderSessionDelegate {
204204

205205
tagReader.progress = { [unowned self] (progress) in
206206
if let dgId = self.currentlyReadingDataGroup {
207-
self.updateReaderSessionMessage( alertMessage: NFCViewDisplayMessage.readingDataGroupProgress(dgId, progress) )
207+
self.updateReaderSessionMessage( alertMessage: NFCViewDisplayMessage.readingDataGroupProgress(dgId, progress, self.labels?["reading"] as? String) )
208208
} else {
209-
self.updateReaderSessionMessage( alertMessage: NFCViewDisplayMessage.authenticatingWithPassport(progress) )
209+
self.updateReaderSessionMessage( alertMessage: NFCViewDisplayMessage.authenticatingWithPassport(progress, self.labels?["reading"] as? String) )
210210
}
211211
}
212212

213213
try await self.startReading( tagReader : tagReader)
214214

215215
} catch let error as NFCPassportReaderError {
216-
let errorMessage = NFCViewDisplayMessage.error(error)
216+
let errorMessage = NFCViewDisplayMessage.error(error, self.labels?["error"] as? String)
217217
self.invalidateSession(errorMessage: errorMessage, error: error)
218218
} catch let error {
219219
Logger.passportReader.debug( "tagReaderSession:failed to connect to tag - \(error.localizedDescription)" )
220-
let errorMessage = NFCViewDisplayMessage.error(NFCPassportReaderError.ConnectionError)
220+
let errorMessage = NFCViewDisplayMessage.error(NFCPassportReaderError.ConnectionError(self.labels?["error"] as? String))
221221
self.invalidateSession(errorMessage: errorMessage, error: NFCPassportReaderError.Unknown(error))
222222
}
223223
}
@@ -264,7 +264,7 @@ extension PassportReader {
264264

265265
try await doActiveAuthenticationIfNeccessary(tagReader : tagReader)
266266

267-
self.updateReaderSessionMessage(alertMessage: NFCViewDisplayMessage.successfulRead)
267+
self.updateReaderSessionMessage(alertMessage: NFCViewDisplayMessage.successfulRead(self.labels?["successfulRead"] as? String))
268268
self.shouldNotReportNextReaderSessionInvalidationErrorUserCanceled = true
269269
self.readerSession?.invalidate()
270270

@@ -279,7 +279,7 @@ extension PassportReader {
279279
guard self.passport.activeAuthenticationSupported else {
280280
return
281281
}
282-
self.updateReaderSessionMessage(alertMessage: NFCViewDisplayMessage.activeAuthentication)
282+
self.updateReaderSessionMessage(alertMessage: NFCViewDisplayMessage.activeAuthentication(self.labels?["activeAuthentication"] as? String))
283283

284284
Logger.passportReader.info( "Performing Active Authentication" )
285285

@@ -309,7 +309,7 @@ extension PassportReader {
309309
// Read COM
310310
var DGsToRead = [DataGroupId]()
311311

312-
self.updateReaderSessionMessage( alertMessage: NFCViewDisplayMessage.readingDataGroupProgress(.COM, 0) )
312+
self.updateReaderSessionMessage( alertMessage: NFCViewDisplayMessage.readingDataGroupProgress(.COM, 0, self.labels?["reading"] as? String) )
313313
if let com = try await readDataGroup(tagReader:tagReader, dgId:.COM) as? COM {
314314
self.passport.addDataGroup( .COM, dataGroup:com )
315315

@@ -353,7 +353,7 @@ extension PassportReader {
353353
DGsToRead = DGsToRead.filter { dataGroupsToRead.contains($0) }
354354
}
355355
for dgId in DGsToRead {
356-
self.updateReaderSessionMessage( alertMessage: NFCViewDisplayMessage.readingDataGroupProgress(dgId, 0) )
356+
self.updateReaderSessionMessage( alertMessage: NFCViewDisplayMessage.readingDataGroupProgress(dgId, 0, self.labels?["reading"] as? String) )
357357
if let dg = try await readDataGroup(tagReader:tagReader, dgId:dgId) {
358358
self.passport.addDataGroup( dgId, dataGroup:dg )
359359
}
@@ -367,7 +367,7 @@ extension PassportReader {
367367
var readAttempts = 0
368368
var nfcPassportReaderError: NFCPassportReaderError
369369

370-
self.updateReaderSessionMessage( alertMessage: NFCViewDisplayMessage.readingDataGroupProgress(dgId, 0) )
370+
self.updateReaderSessionMessage( alertMessage: NFCViewDisplayMessage.readingDataGroupProgress(dgId, 0, self.labels?["reading"] as? String) )
371371

372372
repeat {
373373
do {

ios/NFCPassportReader/TagReader.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ public class TagReader {
289289
Logger.tagReader.error( "Error reading tag: sw1 - 0x\(binToHexRep(sw1)), sw2 - 0x\(binToHexRep(sw2))" )
290290
let tagError: NFCPassportReaderError
291291
if (rep.sw1 == 0x63 && rep.sw2 == 0x00) {
292-
tagError = NFCPassportReaderError.InvalidMRZKey
292+
tagError = NFCPassportReaderError.InvalidMRZKey()
293293
} else {
294294
let errorMsg = self.decodeError(sw1: rep.sw1, sw2: rep.sw2)
295295
Logger.tagReader.error( "reason: \(errorMsg)" )

src/index.tsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,19 @@ export type StartReadingParams = {
3030
};
3131
includeImages?: boolean; // default: false
3232
includeRawData?: boolean; // default: false
33+
labels?: {
34+
title?: string;
35+
cancelButton?: string;
36+
requestPresentPassport?: string;
37+
authenticatingWithPassport?: string;
38+
reading?: string;
39+
activeAuthentication?: string;
40+
successfulRead?: string;
41+
tagNotValid?: string;
42+
moreThanOneTagFound?: string;
43+
invalidMRZKey?: string;
44+
error?: string;
45+
};
3346
};
3447

3548
export type EidReadStatus = 'OK' | 'Error' | 'Canceled';

0 commit comments

Comments
 (0)