原文链接: http://fighting300.com...
大家可能听过NFC这项功能,或者有可能你每天都在使用这个功能,比如当你在进出地铁时闸机扫描地铁卡就用到了NFC技术。
简单来说NFC就是可以让智能手机的NFC模块,可以像读卡器一般,读取电子标签的相关信息,实现NFC手机之间的数据交互或是读取其他IC卡内的数据。NFC(机场通讯),其实由非接触式射频识别(RFID)演变而来,是一种短距高频的无线电技术,在13.56MHz频率运行于20厘米距离内。它的传输速度有106 Kbit/秒、212 Kbit/秒或者424 Kbit/秒三种。目前NFC已通过成为ISO/IEC IS 18092国际标准、ECMA-340标准与ETSI TS 102 190标准。
Core NFC介绍
或者你可能还吐槽过Apple怎么还不支持NFC呢,其实iPhone6已经有NFC硬件了,已支持Apple Pay支付系统,只是接口没开放,终于在今年的WWDC,苹果在iOS11系统上对开发者开放了NFC接口框架Core NFC,虽然目前权限只有只读模式。
Apple的Core NFC可以用于检测NFC(近场通讯)标签和读取包含NDEF(NFC Data Exchange Format)数据1到5类型的标签信息,只是该功能只支持iPhone 7和iPhone 7P及以上的机型。目前Core NFC其实同时有NFC和RFID的API存在,但是RFID可能没有很高的安全性,所以苹果没有推广使用(或者还在开发中)。
NFC Data Exchange Format : NFC数据交换格式,NFC组织约定的NFC tag中的数据格式。NDEF是轻量级的紧凑的二进制格式,可带有URL、vCard和NFC定义的各种数据类型。NDEF的由各种数据记录组成,而各个记录由报头(Header)和有效载荷(Payload)组成,其中NDEF记录的数据类型和大小由记录载荷的报头注明,这里的报头包含3部分,分别为Length、Type和Identifier。
iOS集成开发
项目配置
首先需要让你的AppID添加对NFC的支持,选中NFC Tag Reading后更新Provisioning Profiles即可。
其次在项目中打开Targets->Capabilities下的Near Field Communication Tag Reading选项,Xcode会自动帮你创建NFC entitlement文件。然后你需要在entitlements文件下添加如下内容(该内容新版Xcode已经自动添加并配置完成):
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
<string>NDEF</string>
</array>
随后需要在info.plist中添加隐私标签Privacy - NFC Scan Usage Description
。
<key>NFCReaderUsageDescription</key>
<string>NFC Import</string>
集成Core NFC
集成Core NFC需要用到NFCNDEFReaderSession
类,其为NFCReaderSession的子类,但是基类不能实例化。
和iOS的其他Session一样通过其协议NFCReaderSessionProtocol
方法来处理信息回调的结果。这最重要的一个代理回调是func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages:[NFCNDEFMessage])
方法,用以处理检测到的NDEF消息,messages是一个NFCNDEFMessage的数组,其有一个records数组,包含NFCNDEFPayload对象,该对象存放了真正的数据内容。
import CoreNFC
class MessagesTableViewController: UITableViewController, NFCNDEFReaderSessionDelegate {
// MARK: NFCNDEReaderSessionDelegate
func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) {
// Check invalidation reason from the returned error. Session will be invalidated after the function returns. New session instance is required to restart tag scanning.
}
func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages:[NFCNDEFMessage]) {
// Process read NFCNDEFMessage objects.
for message in messages {
print(" - \(message.records.count) Records:")
for record in message.records {
print("\t- TNF (TypeNameFormat): \(record.typeNameFormat)")
print("\t- Payload: \(String(data: record.payload, encoding: .utf8)!)")
print("\t- Type: \(record.type)")
print("\t- Identifier: \(record.identifier)\n")
}
}
}
// MARK: - Actions
@IBAction func beginScanning(_ sender: Any) {
let session = NFCNDEFReaderSession(delegate: self, queue: nil, invalidatedAfterFirstRead:true)
session.alertMessage = "You can scan NFC-tags by holding them behind the top of your iPhone."
session.begin()
}
NFCReaderSession
还有NFCISO15693ReaderSession
的子类,用于RFID的读取处理,其使用流程和NFCNDEFReaderSession
基本一致,只是代理方法不同,ISO15693是一种特殊的RFID标签,它拥有自己的协议和数据API(NFCISO15693Tag)。但是该类不起作用。。。可能Apple工程师还在开发中吧
Tips
- 注意同时只能实例化一个读取session(系统会把其他的session放在队列里序列化执行)
- Core NFC目前只支持前台扫描,切换到后台会失效
- NFCNDEFReaderSession最大每次扫描60s,超时需要重启
- 可以配置单一Tag或者多Tag读取模式
- 使用提示信息即alertMessage会显示在当前APP的弹出浮层中
获取成功后,即可以根据获取到的信息进行之后的业务流程了。
[相关代码地址]:https://github.com/fighting300/iOS11-Example.git