iOS平台下如何向ISO 14443-4格式NFC标签发送自定义指令?
iOS下通过NFCTagReaderSession发送ISO 14443-4指令读取NFC标签块
要发送30 4F(读取第79块)指令到ISO 14443-4标签,核心是将检测到的标签转换为NFCISO14443Tag类型后调用sendCommand方法,以下是完整实现步骤和代码:
1. 基础配置
确保项目已开启NFC权限:
- 在
Info.plist中添加NFCReaderUsageDescription权限描述 - 勾选项目Capabilities中的Near Field Communication Tag Reading
2. 核心代码实现
import CoreNFC class NFCReaderViewController: UIViewController, NFCTagReaderSessionDelegate { private var nfcSession: NFCTagReaderSession? // 启动NFC会话 func startNFCSession() { guard NFCTagReaderSession.readingAvailable else { print("设备不支持NFC读取") return } nfcSession = NFCTagReaderSession(pollingOption: .iso14443, delegate: self, queue: nil) nfcSession?.begin() } // 检测到标签时触发 func tagReaderSession(_ session: NFCTagReaderSession, didDetect tags: [NFCTag]) { 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 } // 将标签转换为ISO14443类型 guard let isoTag = tag as? NFCISO14443Tag else { session.invalidate(errorMessage: "标签不符合ISO 14443-4标准") return } // 将十六进制指令30 4F转为Data let commandData = Data(hexString: "304F") // 发送指令 isoTag.sendCommand(commandPacket: commandData) { responseData, error in if let error = error { session.invalidate(errorMessage: "发送指令失败:\(error.localizedDescription)") return } // 处理响应数据(示例:转为十六进制字符串) if let response = responseData { let hexResponse = response.hexString print("读取到的响应:\(hexResponse)") session.invalidate() } } } } // NFC会话无效时触发 func tagReaderSession(_ session: NFCTagReaderSession, didInvalidateWithError error: Error) { print("NFC会话无效:\(error.localizedDescription)") nfcSession = nil } } // 扩展Data,方便十六进制字符串和Data互转 extension Data { init?(hexString: String) { let cleanedString = hexString.replacingOccurrences(of: " ", with: "") let length = cleanedString.count guard length % 2 == 0 else { return nil } var data = Data(capacity: length / 2) var index = cleanedString.startIndex while index < cleanedString.endIndex { let nextIndex = cleanedString.index(index, offsetBy: 2) let substring = cleanedString[index..<nextIndex] if let byte = UInt8(substring, radix: 16) { data.append(byte) } else { return nil } index = nextIndex } self = data } var hexString: String { return map { String(format: "%02X", $0) }.joined() } }
关键说明
- 转换标签类型:只有将检测到的
NFCTag转为NFCISO14443Tag,才能调用符合ISO 14443-4标准的sendCommand方法 - 指令转换:十六进制字符串需要先转为
Data对象,上面的Data扩展提供了便捷的转换方法 - 错误处理:务必处理连接失败、标签类型不匹配、指令发送失败等场景,避免会话异常
内容的提问来源于stack exchange,提问作者pankot
相关产品推荐
相关产品推荐

