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

如何从NFC标签读取序列号?解决代码无法获取标识符问题

读取NFC标签的唯一标识符/序列号解决方案

你当前代码中读取的record.identifier是NDEF记录的标识符,并非NFC标签本身的硬件唯一序列号——多数NDEF标签不会给单条记录设置这个字段,因此它为空是正常情况。要获取标签的唯一ID,需要从NFCNDEFTag实例的具体类型中读取,不同标准的NFC标签,读取序列号的方式不同。

修改后的实现代码

func readerSession(_ session: NFCNDEFReaderSession, didDetect tags: [NFCNDEFTag]) {
    guard let tag = tags.first else {
        session.invalidate(errorMessage: "未检测到有效标签")
        return
    }
    
    session.connect(to: tag) { [weak self] error in
        guard let self = self else { return }
        if let error = error {
            session.invalidate(errorMessage: "连接标签失败:\(error.localizedDescription)")
            return
        }
        
        // 根据标签类型读取唯一标识符
        switch tag {
        case let iso15693Tag as NFCISO15693Tag:
            // ISO 15693 标签(如NFC Type 5)的标识符
            let tagIdentifier = iso15693Tag.identifier
            print("标签序列号(ISO15693):\(tagIdentifier.hexString)")
            
        case let iso7816Tag as NFCISO7816Tag:
            // ISO 7816 标签(如NFC Type 4)的序列号,通常在historicalBytes中
            if let historicalBytes = iso7816Tag.historicalBytes {
                // 不同卡的序列号位置可能不同,此处取常见的前8字节
                let tagIdentifier = historicalBytes.prefix(8)
                print("标签序列号(ISO7816):\(tagIdentifier.hexString)")
            }
            
        case let mifareClassicTag as NFCMIFAREClassicTag:
            // MIFARE Classic 标签的标识符
            let tagIdentifier = mifareClassicTag.identifier
            print("标签序列号(MIFARE Classic):\(tagIdentifier.hexString)")
            
        case let mifareULTag as NFCMIFAREULTag:
            // MIFARE Ultralight 标签的标识符
            let tagIdentifier = mifareULTag.identifier
            print("标签序列号(MIFARE Ultralight):\(tagIdentifier.hexString)")
            
        default:
            print("不支持的标签类型")
        }
        
        // 继续读取NDEF内容(如果需要)
        tag.queryNDEFStatus { ndefStatus, capacity, error in
            if let error = error {
                session.invalidate(errorMessage: "查询NDEF状态失败:\(error.localizedDescription)")
                return
            }
            
            guard ndefStatus == .readWrite || ndefStatus == .readOnly else {
                session.invalidate(errorMessage: "标签不支持NDEF")
                return
            }
            
            tag.readNDEF { message, error in
                defer { session.invalidate() }
                
                if let error = error {
                    print("读取NDEF失败:\(error.localizedDescription)")
                    return
                }
                
                guard let message = message else {
                    print("标签无NDEF数据")
                    return
                }
                
                for record in message.records {
                    print("Type name: \(record.typeNameFormat)")
                    print("Payload: \(String(data: record.payload, encoding: .utf8) ?? "无法解析")")
                    // 其他NDEF记录字段可按需读取
                }
            }
        }
    }
}

// 扩展Data,方便将二进制标识符转为十六进制字符串
extension Data {
    var hexString: String {
        return map { String(format: "%02x", $0) }.joined().uppercased()
    }
}

关键说明

  1. 标签类型区分:不同标准的NFC标签(如ISO15693、MIFARE系列)的序列号存储逻辑不同,需要通过类型转换后读取对应属性。
  2. 错误处理:替换了原代码中的强制解包(message!),避免空值崩溃,同时增加了连接、查询阶段的错误提示。
  3. 可读性优化:通过Data扩展将二进制序列号转为十六进制字符串,便于查看和使用。

内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 14:25:21