Core NFC 初体验
随着 WWDC 2017 的落幕,一大批新的技术(像 ARKit、Core ML、Core NFC 等等……)开始逐渐为开发者所知。开发者们又有了新的玩具可以玩一阵子了~
这篇文章就单独拿 Core NFC 来说吧,毕竟它和我们的生活紧密相关。
注意:浏览本文中的部分图片需要科学上网。
这次苹果爸爸只开始开放了 NFC 的读取权限,所以想拿 iPhone 当公交卡的同学,可能又要伤心了。但是拿 iPhone 来当个读卡器什么的,还是能玩一玩的~
然鹅,只有那些拥有 iOS 11 系统的 iPhone 7/7P 的同学,才能拥有这些尊贵的特权。

这次放出的 Core NFC 可以说是非常的轻量了,使用起来简直不能再简单一点。上图是 WWDC 上苹果提供的技术细分图,可以说基本涵盖了所有的格式。可以实现检测 NFC 标签 (NFC tags) 并读取包含 NDEF(NFC Data Exchange Format) 的数据。
实现步骤
配置
- 在开发者后台给你的 App ID 添加 NFC 读取权限。

- 在 Info.plist 里添加如下信息,用来提示用户获取设备的 NFC 读取权限。
<key>NFCReaderUsageDescription</key>
<string>some description...</string>
- 在 entitlements 文件里添加如下信息。
<key>com.apple.developer.nfc.readersession.formats</key>
<array>
<string>NDEF</string>
</array>
代码实现
Objective-c
- 导入 CoreNFC 头文件
#import <CoreNFC/CoreNFC.h>
- 设置代理
@interface YourViewController : UIViewController <NFCNDEFReaderSessionDelegate>
- 在 .m 中实现如下代码
- (void)viewDidLoad {
[super viewDidLoad];
NFCNDEFReaderSession *session = [[NFCNDEFReaderSession alloc] initWithDelegate:self queue:dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT) invalidateAfterFirstRead:NO];
[session beginSession];
}
- (void)readerSession:(nonnull NFCNDEFReaderSession *)session didDetectNDEFs:(nonnull NSArray<NFCNDEFMessage *> *)messages {
for (NFCNDEFMessage *message in messages) {
for (NFCNDEFPayload *payload in message.records) {
NSLog(@"Payload data:%@",payload.payload);
}
}
}
- (void)readerSession:(NFCNDEFReaderSession *)session didInvalidateWithError:(NSError *)error{
NSLog(@"%@",error);
}
- 你可以用如下方法停止 session
[session invalidateSession];
Swift
- 导入 CoreNFC
import CoreNFC
- 设置代理
class YourViewController: UIViewController, NFCNDEFReaderSessionDelegate
- 实现如下代码
override func viewDidLoad() {
super.viewDidLoad()
let session = NFCNDEFReaderSession(delegate: self,
queue: DispatchQueue(label: "queueName", attributes: .concurrent), invalidateAfterFirstRead: false)
session.begin()
}
func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) {
for message in messages {
for record in message.records {
print(record.payload)
}
}
}
func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) {
print(error.localizedDescription)
}
- 你可以用如下方法停止 session
session.invalidate()
注:每个 session 的扫描时间最多60s,如果超时需要再次开启 session。
以上,就是最简单的代码实现。
如果不出意外的话,编译并运行刚刚的代码,在 App 启动的时候,会出现如下场景...

恭喜!你的第一个 NFC Demo 已经完成,快用你的卡片试一下吧!