NFC(近场通信)在生活中有很多使用场景,最常见的就是支付,除了刚开始的Apple Pay,到现在的交通卡,一些智能门锁等,都是利用了NFC的技术,可以说NFC的应用极大地提高了生活效率。但是iPhone上的NFC开放给开发者使用的时间稍晚了一点,仅在iPhone 7及其以上的机型并且iOS 11及其以上的系统开发者才有权限使用NFC,而且目前也只是初步的开放,仅支持NFC Tags(标签)的读取。好了,话不多说,进入正题。
这个NFC应用大致原理是扫描含有NFC芯片的卡片,在iPhone的屏幕上,能显示观众随机抽取的卡片对应的图片。自己在开发过程中也是遇到了一些坑,网上的相关资料也不是很多,在此分享一下心得。
首先需要像推送一样打开Capabilities里面的NFC开关,然后在plist文件里添加使用权限说明,在使用NFC时需要导入NFC框架,同时遵守 NFCNDEFReaderSessionDelegate:
import CoreNFC
class ShowViewController: UIViewController, NFCNDEFReaderSessionDelegate
定义一个NFC会话Session的变量:
var nfcSession: NFCNDEFReaderSession?
在viewDidLoad()方法里初始化这个变量并开启会话:
/// invalidateAfterFirstRead 属性表示是否需要识别多个NFC标签,如果是true,则会话会在第一次识别成功后终止;
/// 不过有一种例外情况,就是如果响应了协议中失败的方法,不管是true还是false,会话都会被终止
nfcSession = NFCNDEFReaderSession(delegate: self, queue: nil, invalidateAfterFirstRead: false)
nfcSession?.begin()
最后实现协议方法,协议方法有两个,一个是成功,一个是失败:
/// 读取失败
func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error)
{}
/// 读取成功
func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage])
{}
在成功回调方法里面,有一个参数message,这个参数是一个数组,数组里的对象是NFCNDEFMessage类型,这个类型有一个属性是records,这个属性也是一个数组,但是里面的对象是NFCNDEFPayload类型,扫描芯片的内容就在这里,所以这里遍历取出扫描的内容:
for myPayload:NFCNDEFPayload in (messages.first?.records)!
{
let data = myPayload.payload
imageName = String(data: data, encoding: .utf8)
///此处省略逻辑代码
}
session.invalidate()
注意❗️❗️❗️
1、这里的payload是Data类型,如果需要字符串等其他类型,要进行相应的转换。
2、关于卡片读取,这里的卡片一定要支持NDEF格式
3、会话可以读取一个或多个标签,在读取单个标签的时候,读取完成后会话自动终止。如果读取多个标签,会话会一直持续直到程序主动终止会话或者60秒后(60秒是一个最大的节点)。