Swift(iOS)中NFC扫描类不兼容NFCNDEFReaderSessionDelegate协议问题排查
NFCNDEFReaderSessionDelegate协议不兼容问题排查与解决
问题背景
我在iOS应用中使用Swift编写了DniNFCViewController类实现NFC扫描功能,代码如下,但IDE报错:
Type 'DniNFCViewController' does not conform to protocol 'NFCNDEFReaderSessionDelegate'
IDE提示需添加readerSession方法,但我已实现协议要求的所有方法,且该类在新项目中可正常运行。
实现代码
// // DniNFCViewController.swift // SSLSignature // // Created by Ismael Márquez on 20/2/24. // Copyright © 2024 aralink. All rights reserved. // import UIKit import CoreNFC class DniNFCViewController: UIViewController, NFCNDEFReaderSessionDelegate { var nfcSession: NFCNDEFReaderSession? override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } @IBAction func startNFCSession(_ sender: Any) { nfcSession = NFCNDEFReaderSession(delegate: self, queue: nil, invalidateAfterFirstRead: false) nfcSession?.begin() } // MARK: - NFCNDEFReaderSessionDelegate func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) { print("Session invalidated with error: \(error.localizedDescription)") } func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) { // Handle NFC tag detection here for message in messages { for record in message.records { // Process NDEF records // This is where you would handle the data read from the NFC tag print("Record payload: \(record.payload)") } } } }
原因分析
- iOS版本方法签名变更:
NFCNDEFReaderSessionDelegate的核心方法在iOS 13发生了变更——旧的didDetectNDEFs被标记为过时,新增了readerSession(_:didDetect:)方法。如果当前项目部署目标低于iOS 13,或编译环境与新项目存在版本差异,会触发协议不兼容检测。 - IDE缓存异常:Xcode的编译缓存可能出现逻辑错误,导致错误提示与实际代码状态不符。
- 命名冲突:项目中可能存在自定义的同名类/协议(如
NFCNDEFMessage),与CoreNFC框架的原生类型产生冲突,导致协议匹配失败。
解决方法
1. 适配多版本iOS协议方法
同时实现新旧版本的协议方法,覆盖不同iOS版本的要求:
// 兼容iOS 13及以上的新方法 @available(iOS 13.0, *) func readerSession(_ session: NFCNDEFReaderSession, didDetect tags: [NFCNDEFTag]) { guard let tag = tags.first else { return } session.connect(to: tag) { error in if let error = error { session.invalidate(errorMessage: "连接失败: \(error.localizedDescription)") return } tag.queryNDEFStatus { status, _, error in if let error = error { session.invalidate(errorMessage: "读取状态失败: \(error.localizedDescription)") return } switch status { case .notSupported: session.invalidate(errorMessage: "标签不支持NDEF") case .readOnly, .readWrite: tag.readNDEF { message, error in DispatchQueue.main.async { if let error = error { session.invalidate(errorMessage: "读取失败: \(error.localizedDescription)") } else if let message = message { // 复用原有逻辑处理NDEF消息 for record in message.records { print("Record payload: \(record.payload)") } } session.invalidate() } } @unknown default: session.invalidate(errorMessage: "未知标签状态") } } } } // 保留旧方法兼容iOS 12及以下 func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) { for message in messages { for record in message.records { print("Record payload: \(record.payload)") } } }
2. 清理Xcode缓存
执行Product > Clean Build Folder(快捷键Cmd+Shift+K),然后重启Xcode并重新编译项目,清除异常缓存。
3. 排查命名冲突
检查项目中是否存在自定义的NFCNDEFReaderSessionDelegate、NFCNDEFMessage等类型,重命名冲突的自定义类型,确保与CoreNFC框架的原生类型完全区分。
4. 确认框架与部署目标
- 确认项目已正确导入
CoreNFC框架,且部署目标不低于iOS 11(CoreNFC最低支持版本)。 - 检查项目的iOS SDK版本与新项目是否一致,避免因SDK版本差异导致的协议方法匹配问题。
内容的提问来源于stack exchange,提问作者Marquez_32
相关产品推荐
相关产品推荐

