You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Core NFC读取Vigik徽章(ISO/IEC 7816-5:2004)遇检测问题求助

使用Core NFC读取Vigik徽章(ISO/IEC 7816-5:2004)遇检测问题求助

各位开发者好,我目前开发的一款App使用Core NFC模块来检测NFC卡片,MIFARE、ISO 14443这类标签都能正常识别并读取数据,但唯独Vigik徽章始终无法被检测到。我已经在App的Entitlements.plist中正确注册了Vigik徽章对应的AID,扫描操作对其他卡片都有效,唯独Vigik徽章没有任何响应,实在找不到问题所在,想请大家帮忙排查一下。

以下是我的实现细节:

  • AID注册:已在权限文件中配置Vigik徽章的正确AID,并且通过NFCTagReaderSession设置了对应的标签轮询类型。
  • 其他卡片兼容性:ISO 14443、MIFARE类型的NFC卡均能被正常检测、读取,功能完全正常。

附上我的ViewController代码:

//
//  ViewController.swift
//  testNFCCOre
//
//  Created by mind on 12/11/24.
//

import UIKit
import CoreNFC

class ViewController: UIViewController, NFCTagReaderSessionDelegate {
    var nfcSession: NFCReaderSession?

    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
    @IBAction func onTapScan(_ sender: Any) {
        startScanning()
    }
    
    func startScanning() {
        guard NFCTagReaderSession.readingAvailable else {
            print("NFC is not supported on this device.")
            return
        }
        
        // Create a session for raw tag reading
        nfcSession = NFCTagReaderSession(pollingOption: [.iso14443,.iso18092,.iso15693], delegate: self, queue: DispatchQueue.main)
        
        // Begin the session
        nfcSession?.begin()
    }
    
    // Called when the session becomes active
    func tagReaderSessionDidBecomeActive(_ session: NFCTagReaderSession) {
        print("NFC session is active.")
        // You can inform the user that the NFC reader is active or show a message
    }
    
    // Called when the session is invalidated (e.g., user cancels or an error occurs)
    func tagReaderSession(_ session: NFCTagReaderSession, didInvalidateWithError error: Error) {
        if let error = error as? NFCReaderError {
            switch error.code {
            case .readerSessionInvalidationErrorUserCanceled:
                print("User canceled the session.")
            case .readerSessionInvalidationErrorSessionTimeout:
                print("Session timed out.")
            case .readerSessionInvalidationErrorSystemIsBusy:
                print("System is busy. Please try again.")
            default:
                print("Session invalidated with error: \(error.localizedDescription)")
            }
        } else {
            print("Session invalidated with error: \(error.localizedDescription)")
        }
    }
    
    // Called when the session detects NFC tags
    func tagReaderSession(_ session: NFCTagReaderSession, didDetect tags: [NFCTag]) {
        let tag = tags.first!
        session.connect(to: tag) { error in
            if let error = error {
                print("Connection failed: \(error.localizedDescription)")
                return
            }
            print("Tag connected successfully!")
            
            // Continue processing the tag depending on its type
            for tag in tags {
                switch tag {
                case .miFare(let mifareTag):
                    print("MIFARE tag detected: \(mifareTag)")
                    self.handleMifareTag(mifareTag)
                    
                case .feliCa(let feliCaTag):
                    print("FeliCa tag detected: \(feliCaTag)")
                    self.handleFeliCaTag(feliCaTag)
                    
                case .iso7816(let iso7816Tag):
                    print("ISO 7816 tag detected: \(iso7816Tag)")
                    
                    let aidData = Data([
                        0xA0, 0x00, 0x00, 0x00, 0x86, 0x32, 0x05, 0x49,
                        0x47, 0x49, 0x4B, 0xAE, 0x5F, 0x33
                    ])

                    // Create APDU SELECT command
                    let command = NFCISO7816APDU(
                        instructionClass: 0x00,
                        instructionCode: 0xA4,
                        p1Parameter: 0x04,
                        p2Parameter: 0x00,
                        data: aidData,
                        expectedResponseLength: -1
                    )

                    // Send the APDU command
                    iso7816Tag.sendCommand(apdu: command) { response, sw1, sw2, error in
                        if let error = error {
                            print("Error sending APDU: \(error.localizedDescription)")
                            return
                        }
                        
                        // Parse the response
                        print("Response: \(response)")
                        print("Status words: SW1=\(sw1), SW2=\(sw2)")
                        
                        // Process specific application template if needed
                        if sw1 == 0x90 && sw2 == 0x00 {
                            print("Application selected successfully!")
                        } else {
                            print("Application selection failed with status words \(sw1), \(sw2)")
                        }
                    }


                    self.handleIso7816Tag(iso7816Tag)
                    
                    
                case .iso15693(let nfcATag):
                    print("ISO 15693 tag detected: \(nfcATag)")
                    self.handleNfcATag(nfcATag)
                    
                default:
                    print("Unknown tag type detected.")
                }
            }
            session.invalidate()
        }
    }
    
    // Handle MIFARE tag
    func handleMifareTag(_ mifareTag: NFCMiFareTag) {
        // Process MIFARE tag data
        print("MIFARE UID: \(mifareTag.identifier)")
    }
    
    // Handle FeliCa tag
    func handleFeliCaTag(_ feliCaTag: NFCFeliCaTag) {
        // Print available information from NFCFeliCaTag
        print("FeliCa tag detected.")
    }
    
    // Handle ISO 7816 tag (smart cards)
    func handleIso7816Tag(_ iso7816Tag: NFCISO7816Tag) {
        // Process ISO 7816 tag data
        print("Tag Identifier: \(iso7816Tag.identifier.hexString())")
        let hexString = "4a6f686e"  // Hex for "John"
        if let decodedText = hexStringToText(hexString: iso7816Tag.identifier.hexString()) {
            print("Decoded text: \(decodedText)")  // Outputs: John
        }
        print("Application Data: \(String(describing: iso7816Tag.applicationData))")
        print("Historical Bytes: \(String(describing: iso7816Tag.historicalBytes))")
        if let historicalBytes = iso7816Tag.historicalBytes {
            let hexString = historicalBytes.map { String(format: "%02hhx", $0) }.joined()
            print("Historical Bytes as Hex: \(hexString)")
        }
        print("Selected AID: \(iso7816Tag.initialSelectedAID)")
    }
    
    // Handle NFC-A tag
    func handleNfcATag(_ nfcATag: NFCISO15693Tag) {
        // Process NFC-A tag data
        print("NFC-A UID: \(nfcATag.identifier)")
    }
    
    // Convert Hex String to Text
    func hexStringToText(hexString: String) -> String? {
        var hex = hexString
        var data = Data()
        while hex.count > 0 {
            let c = hex.prefix(2)
            hex = String(hex.dropFirst(2))
            if let byte = UInt8(c, radix: 16) {
                data.append(byte)
            }
        }
        return String(data: data, encoding: .utf8)
    }
}

// Convert Data to Hex String
extension Data {
    func hexString() -> String {
        return self.map { String(format: "%02hhx", $0) }.joined()
    }
    
    func hexStringToData(hexString: String) -> Data? {
        var data = Data()
        // Ensure the hex string is in valid form (even length)
        let cleanedHexString = hexString.replacingOccurrences(of: " ", with: "").uppercased()
        // Process every pair of characters (each byte)
        var startIndex = cleanedHexString.startIndex
        while startIndex < cleanedHexString.endIndex {
            let endIndex = cleanedHexString.index(startIndex, offsetBy: 2)
            let hexPair = String(cleanedHexString[startIndex..<endIndex])

            if let byte = UInt8(hexPair, radix: 16) {
                data.append(byte)
            } else {
                print("Invalid hex pair: \(hexPair)")
                return nil
            }
            startIndex = endIndex
        }
        return data
    }
}

备注:内容来源于stack exchange,提问作者Raj Saija

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 10:09:33