This is my code:
HCE app:
@available(iOS 17.4, *)
func cardSession(accessCode: String) {
print("Access code: \(accessCode)")
let ProcessAPDU: (_ capdu: Data) -> Data = { capdu in
guard let responseAPDU = accessCode.data(using: .utf8) else {
print("Failed to convert access code to Data")
return Data()
}
return responseAPDU
}
Task {
guard NFCReaderSession.readingAvailable,
CardSession.isSupported,
await CardSession.isEligible else {
self.showQRCode()
return
}
self.cancelSession()
do {
(UIApplication.shared.delegate as? AppDelegate)?.currentCardSession = try await CardSession()
} catch {
self.showQRCode()
return
}
guard let cardSession = (UIApplication.shared.delegate as? AppDelegate)?.currentCardSession as? CardSession else {
print("Card session is nil or not of type CardSession")
self.showQRCode()
return
}
for try await event in cardSession.eventStream {
switch event {
case .sessionStarted:
print("Session started")
cardSession.alertMessage = NSLocalizedString("Communicating with ticket reader.", comment: "")
if await !cardSession.isEmulationInProgress {
try await cardSession.startEmulation()
}
case .readerDetected:
print("Reader detected")
if await !cardSession.isEmulationInProgress {
try await cardSession.startEmulation()
}
case .readerDeselected:
print("Reader deselected")
case .received(let cardAPDU):
do {
let responseAPDU = ProcessAPDU(cardAPDU.payload)
try await cardAPDU.respond(response: responseAPDU)
await cardSession.stopEmulation(status: .success)
print("Received APDU: \(cardAPDU.payload)")
} catch {
await cardSession.stopEmulation(status: .failure)
print("Error processing APDU: \(error.localizedDescription)")
}
self.cancelSession()
case .sessionInvalidated(reason: let reason):
print("Session invalidated: \(reason)")
cardSession.alertMessage = NSLocalizedString("Ending communication with ticket reader.", comment: "")
@unknown default:
print("Unknown event: \(event)")
break
}
}
}
}
Reader app:
func startNFCSession() {
nfcSession = NFCTagReaderSession(pollingOption: [.iso14443], delegate: self, queue: nil)
nfcSession?.alertMessage = NSLocalizedString("Hold the device close to scan the ticket.", comment: "")
nfcSession?.begin()
}
func tagReaderSession(_ session: NFCTagReaderSession, didDetect tags: [NFCTag]) {
guard let tag = tags.first else {
session.invalidate(errorMessage: NSLocalizedString("No tags found", comment: ""))
return
}
guard case let .iso7816(iso7816Tag) = tag else {
session.invalidate(errorMessage: NSLocalizedString("Tag is not ISO7816", comment: ""))
return
}
Task { [iso7816Tag] in
do {
try await session.connect(to: tag)
do {
let apdu = NFCISO7816APDU(instructionClass: 0x00,
instructionCode: 0xA4,
p1Parameter: 0x04,
p2Parameter: 0x00,
data: Data([0xF0, 0x01, 0x02, 0x03, 0x04, 0x05]),
expectedResponseLength: -1)
var (data, sw1, sw2) = try await iso7816Tag.sendCommand(apdu: apdu)
print("Response: \(data), SW1: \(sw1), SW2: \(sw2)")
// Verificar que la respuesta sea válida
if sw1 == 0x90 && sw2 == 0x00 {
if let accessCode = String(data: data, encoding: .utf8) {
print("Access Code: \(accessCode)")
self.verifyTicket(self.getSectors(), accessCode)
session.invalidate()
} else {
print("Failed to decode access code")
session.invalidate(errorMessage: NSLocalizedString("Failed to decode access code", comment: ""))
}
} else if sw1 == 0x6A && sw2 == 0x82 {
session.invalidate(errorMessage: NSLocalizedString("File not found", comment: ""))
} else if sw1 == 0x6A && sw2 == 0x86 {
session.invalidate(errorMessage: NSLocalizedString("Incorrect parameters P1-P2", comment: ""))
} else {
session.invalidate(errorMessage: String(format: NSLocalizedString("Invalid response: %02x%02x", comment: ""), sw1, sw2))
}
} catch {
print("Sending comment error: \(error.localizedDescription)")
session.invalidate(errorMessage: String(format: NSLocalizedString("Error sending command: %@", comment: ""), error.localizedDescription))
}
} catch {
if let nfcReaderError = error as? NFCReaderError {
print(nfcReaderError.code)
print(nfcReaderError.localizedDescription)
session.invalidate(errorMessage: String(format: NSLocalizedString(nfcReaderError.localizedDescription, comment: "")))
} else {
print(error.localizedDescription)
session.invalidate(errorMessage: String(format: NSLocalizedString("Connection error: %@", comment: ""), error.localizedDescription))
}
}
}
}