如何从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() } }
关键说明
- 标签类型区分:不同标准的NFC标签(如ISO15693、MIFARE系列)的序列号存储逻辑不同,需要通过类型转换后读取对应属性。
- 错误处理:替换了原代码中的强制解包(
message!),避免空值崩溃,同时增加了连接、查询阶段的错误提示。 - 可读性优化:通过
Data扩展将二进制序列号转为十六进制字符串,便于查看和使用。
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

