-1

I am developing an iOS app and would like to scan smart cards (such as debit or credit cards) via NFC and extract information such as the card number, cardholder name, card type (e.g., Visa, MasterCard), and expiry date. I understand that iOS supports NFC, but I'm unclear about what kind of data can be accessed from NFC-enabled cards. Is there any way to securely extract this information on iOS using frameworks like Core NFC?

I'm scanning NFC by this NFCTagReaderSession implementation is below but can't extract the card details:

@IBAction func nfcClick(_ sender: Any) {
    self.addHapticFeedback()
    
    guard NFCTagReaderSession.readingAvailable else {
        self.addErrorHapticFeedback()
        
        let alert = UIAlertController(title: "Scanning Not Supported", message: "This device doesn't support tag scanning.", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil))
        self.present(alert, animated: true, completion: nil)
        return
    }
    
    self.session = NFCTagReaderSession(pollingOption: .iso14443, delegate: self)
    self.session?.alertMessage = "Hold your iPhone 📱 Near the NFC Tag"
    self.session?.begin()
    
}

extension DashboardVC: NFCTagReaderSessionDelegate {
func tagReaderSessionDidBecomeActive(_ session: NFCTagReaderSession) {
    print("Session Activated.")
}

func tagReaderSession(_ session: NFCTagReaderSession, didInvalidateWithError error: any Error) {
    print("Error with Launching Session and description is:", error.localizedDescription)
}

func tagReaderSession(_ session: NFCTagReaderSession, didDetect tags: [NFCTag]) {
    print("Connecting To Tag")
    if tags.count > 1 {
        session.alertMessage = "More Than One Tag Detected, Please try again"
        session.invalidate()
        return
    }
    
    let tag = tags.first!
    
    session.connect(to: tag) { (error) in
        if let error = error {
            session.invalidate(errorMessage: "Connection Failed: \(error.localizedDescription)")
            return
        }
        
        print(tag, "*******")
        
        switch tag {
        case .miFare(let sTag):
            let UID = sTag.identifier.map { String(format: "%.2hhx", $0)}.joined()
            print("UID:", UID)
            session.alertMessage = "UID Captured"
            session.invalidate()
            
            DispatchQueue.main.async {
                print("Tag Detected")
            }
            
        case .iso15693(let sTag):
            let UID = sTag.identifier.map { String(format: "%.2hhx", $0)}.joined()
            print("ISO 15693 UID:", UID)
            session.alertMessage = "ISO 15693 Tag Detected"
            session.invalidate()
            
        case .iso7816(let sTag):
            print("ISO 7816 Tag Detected")
            
            let UID = sTag.identifier.map { String(format: "%.2hhx", $0) }.joined()
            print("ISO 7816 UID:", UID)
            
            //Attempt to read ATR (Answer To Reset)
          //                let atr = sTag.atr.map { String(format: "%.2hhx", $0) }.joined()
          // print("ISO 7816 ATR:", atr)
            
            session.invalidate()
            
        default:
            session.invalidate(errorMessage: "Unsupported tag type.")
            print("Unsupported tag type.")
        }
    }
}
}

0

Browse other questions tagged or ask your own question.