Highlight
iOS 14 让 Core NFC 的 tag API completion handler 采用 Result enum,并扩展 ISO15693 的大容量内存和安全操作支持,开发者处理 NFC 读写结果时能直接按成功或失败分支编写代码。
核心内容
NFC 的难点通常不在扫描动作本身,而在扫描之后的 App 流程。一个停车计费器、共享滑板车、充电桩或餐厅菜单贴上 NFC tag 后,用户希望拿 iPhone 一碰就进入正确页面。Core NFC 负责把实体对象上的 tag 读出来,再把数据交给 App。
在 iPhone 7 之后,App 可以启动最长 60 秒的 NFC 读取 session。到 iPhone XS 开始,如果屏幕点亮,并且 NFC Forum NDEF message 里包含 Universal Link,系统还能在后台读 tag,显示通知横幅。用户点横幅后,这条 NDEF message 会以 NSUserActivity 的形式进入 App 的 UIApplicationDelegate restoration handler。
这场 session 的重点落在两个开发细节上。第一,Core NFC 在 tag API 里采用 Swift 的 Result enum,把成功结果和错误结果放进同一个 completion handler 参数。第二,NFCISO15693Tag 获得 ISO15693 第三版规范里的增强能力,覆盖更大内存 tag 和安全操作。
这两个变化都面向真实设备调试。开发者不再需要从多个可选返回值里判断一次 tag 命令到底成功还是失败;处理 ISO7816、MIFARE 或 ISO15693 tag 时,也能把成功数据和错误路径分开写清楚。
详细内容
NDEF 与后台标签入口
(01:17)Core NFC 的基础模型是一个最长 60 秒的读取 session。演讲明确提到,Core NFC 支持 NDEF reading and writing,也支持 ISO7816、FeliCa、MIFARE 和 ISO15693 等 native tag protocol。
NFC tag contains an NFC Forum NDEF message with a universal link
-> iPhone XS or later reads the tag in the background while the screen is on
-> the system shows a notification banner
-> the user taps the banner
-> the app receives the NDEF message as NSUserActivity via UIApplicationDelegate restorationHandler
关键点:
- 后台读取要求 NDEF message 里包含 Universal Link。
- 系统先展示通知横幅,用户点击后才把数据交给 App。
- App 侧收到的是
NSUserActivity,入口在UIApplicationDelegate的 restoration handler。 - 其他 native tag protocol 仍然通过 Core NFC 的 reader session 在 App 内处理。
Result enum 让 ISO7816 命令更清楚
(02:48)iOS 14 之前,ISO7816 tag 的 send command completion handler 有四个参数,App 需要先检查可选的 error,再解析其他参数。iOS 14 的新签名返回 Result<NFCISO7816ResponseAPDU, Error>,成功时拿到 NFCISO7816ResponseAPDU,失败时拿到 Error。
detectedTag.sendCommand(apdu: apdu) { (result: Result<NFCISO7816ResponseAPDU, Error>) in
switch result {
case .success(let responseAPDU):
/// Handle NFCISO7816ResponseAPDU object.
case .failure(let error):
/// Handle Error object.
}
}
关键点:
detectedTag.sendCommand(apdu: apdu)把 APDU 命令发送给检测到的 ISO7816 tag。- completion handler 只接收一个
result,类型是Result<NFCISO7816ResponseAPDU, Error>。 .success(let responseAPDU)对应成功读取 tag 后得到的响应对象。.failure(let error)对应命令失败后的错误对象。switch result让成功路径和失败路径在代码结构上分开。
MIFARE 写入也改成 Result 处理
(03:49)演讲用 WWDC 2019 的 NFCFishTag sample project 演示迁移:在 CouponViewController 的 write function 里,把 sendMiFareCommand 换成新的 Result 签名。成功分支处理返回的 data,错误分支处理 error。
// You need to zero-pad the data to fill the block size
if blockData.count < blockSize {
blockData += Data(count: blockSize - blockData.count)
}
let writeCommand = Data([writeBlockCommand, offset]) + blockData
tag.sendMiFareCommand(commandPacket: writeCommand) { (response: Result<Data, Error>) in
switch (response) {
case .success(let responseData):
if responseData[0] != successCode {
self.readerSession?.invalidate(errorMessage: "Write tag error. Please try again.")
return
}
let newSize = data.count - blockSize
if newSize > 0 {
self.write(data.suffix(newSize), to: tag, offset: (offset + 1))
} else {
self.readerSession?.invalidate()
}
case .failure(let error):
let message = "Write tag error: \(error.localizedDescription). Please try again."
self.readerSession?.invalidate(errorMessage: message)
}
}
关键点:
- 写入前先把
blockData补到blockSize,这是官方片段里的第一步。 writeCommand由写入命令、偏移量和当前 block 数据拼接而成。sendMiFareCommand的 completion handler 返回Result<Data, Error>。.success(let responseData)分支检查responseData[0]是否等于successCode。- 写入后还有剩余数据时,代码递归调用
self.write,并把offset加一。 .failure(let error)分支把错误信息传给readerSession?.invalidate(errorMessage:)。
ISO15693 增强覆盖大容量与安全操作
(04:37)Core NFC 在 NFCISO15693Tag 协议中加入 ISO15693 第三版 2019 规范定义的增强功能。演讲给出的用途很具体:更大内存大小的 tag,以及安全操作。
NFCISO15693Tag enhancements mentioned in the session:
- fast reading multiple blocks
- extended write multiple blocks
- authenticate
- key update
- challenge
- read buffer
- extended get multiple blocks security status
- extended fast read multiple blocks
- send request
关键点:
fast reading multiple blocks和extended fast read multiple blocks面向多 block 读取。extended write multiple blocks面向扩展写入。authenticate、key update和challenge属于安全相关操作。send request是新的 generic send command,用来发送 App 自己需要的任意数据包。- 这一组能力只在演讲中以功能签名列表出现,文章不补写未提供的 Swift 方法签名。
核心启发
-
做一个现场标签写入工具:给门店、展台或设备贴纸写入 NDEF URL。为什么值得做:session 和官方资源都指向从 iPhone 创建 NFC tag 的场景。怎么开始:使用
NFCNDEFReaderSession处理 NDEF reading and writing,先写入一个 Universal Link,再用真实 iPhone 验证后台读取路径。 -
把停车、租车或充电入口贴到实体设备上:让用户碰一下 tag 后进入支付或启动页面。为什么值得做:演讲把 parking meters、scooter rental 和 electric car charging station 列为 Core NFC 的典型场景。怎么开始:让 tag 的 NDEF message 包含 Universal Link,App 从
NSUserActivity恢复具体设备或站点上下文。 -
做 ISO15693 库存巡检或设备维护 App:用 iPhone 读取大容量 ISO15693 tag 上的状态数据。为什么值得做:iOS 14 增加的 ISO15693 增强功能覆盖多 block 读取、扩展写入和安全操作。怎么开始:用
NFCTagReaderSession连接 ISO15693 tag,再按设备协议选择 fast read、extended write 或 authenticate。 -
给老协议 tag 做调试面板:把 ISO7816、MIFARE、FeliCa 和 ISO15693 的命令响应记录下来。为什么值得做:Core NFC 支持这些 native tag protocol,iOS 14 的
Result签名让错误路径更清楚。怎么开始:先接入官方sendCommand或sendMiFareCommand片段,把.success的响应和.failure的错误分别写进日志。
关联 Session
- What’s new in Universal Links — 解释 Universal Links 与 Associated Domains,适合补齐 NDEF 后台标签跳转到 App 的链接基础。
- Configure and link your App Clips — 讲解 App Clip 如何通过 NFC、QR code、App Clip Code 和网页链接被调用。
- Explore App Clips — 说明如何把 NFC 等真实世界入口设计成短小、聚焦的 App Clip。
- Streamline your App Clip — 补充 NFC 触发后常见的短流程交易、通知和完整 App 过渡设计。
评论
GitHub Issues · utterances