一、介绍
NFC技术是由非接触式射频识别(RFID)演变而来,由飞利浦半导体(现恩智浦半导体公司)、诺基亚和索尼共同研制开发,其基础是RFID及互连技术。近场通信(Near Field Communication,NFC)是一种短距高频的无线电技术,在13.56MHz频率运行于10厘米距离内。其传输速度有106 Kbit/秒、212 Kbit/秒或者424 Kbit/秒三种。
从iPhone的历代机型配置中,可以看出在iPhone6及以上机型都拥有了支持NFC功能的固件,但是一直不开放给开发者使用,直到iOS11
才开放仅有的具有读取NDEF
格式的功能,并且需要iPhone7
或者iPhone7 Plus
才支持使用。
官方介绍,NFC有五种的类型,如图
二、API详解
1. 会话
1.1 NFCReaderSession
//是否已经启动并准备使用@property(nonatomic, getter=isReady, readonly) BOOL ready;//开始会话- (void)beginSession;//关闭会话- (void)invalidateSession;//告知用户在程序中使用NFC的说明,当扫描时该信息将显示给用户,该属性与NFCReaderUsageDescription键中的不一样@property(nonatomic, copy) NSString *alertMessage;复制代码
1.2 NFCNDEFReaderSession
从类的名称可以看出,这个类是用来读取NDEF
格式数据的会话的。继承于NFCReaderSession
/* 初始化会话 * delegate 会话的回调 * queue 线程 * invalidateAfterFirstRead 第一NDEF读取完毕后是否停止会话 * * 当会话为读取多个NDEF时,每次读取成功都会通过代理回调 * 读取多个NDEF时,会话会一直到调用终止活动API或者超时等才会停止会话 * * 如果第一个NDEF读取成功便自动终止,这种情况下,通过readerSession:didInvalidateWithError:回调,此时状态为NFCReaderSessionInvalidationErrorFirstNDEFTagRead */- (instancetype)initWithDelegate:(id)delegate queue:(dispatch_queue_t)queue invalidateAfterFirstRead:(BOOL)invalidateAfterFirstRead;复制代码
//设备是否支持NFC读取标签@property(class, nonatomic, readonly) BOOL readingAvailable;复制代码
//读取到信息时回调- (void)readerSession:(NFCNDEFReaderSession *)session didDetectNDEFs:(NSArray*)messages;//发生错误或者无效时回调- (void)readerSession:(NFCNDEFReaderSession *)session didInvalidateWithError:(NSError *)error;复制代码
2. 标签
2.1 NFCTag
//检测到的标签是否可用@property(nonatomic, getter=isAvailable, readonly) BOOL available;//获取会话@property(nonatomic, weak, readonly) idsession;//标签类型@property(nonatomic, readonly, assign) NFCTagType type;复制代码
2.2 NFCTagCommandConfiguration
//最大的重置次数,最多为256,默认为0@property(nonatomic, assign) NSUInteger maximumRetries;//重试的时间间隔,默认为0@property(nonatomic, assign) NSTimeInterval retryInterval;复制代码
3. NDEFMessage
3.1 NFCNDEFPayload 消息载体
//标识,由NDEF规范定义@property(nonatomic, copy) NSData *identifier;//载体中的数据,由NDEF规范定义@property(nonatomic, copy) NSData *payload;//载体的类型,由NDEF规范定义@property(nonatomic, copy) NSData *type;//载体的类型名称格式,由NDEF规范定义@property(nonatomic, assign) NFCTypeNameFormat typeNameFormat;复制代码
NFCTypeNameFormat定义的类型:
- TypeNameFormatAbsoluteURI 统一使用资源标识标准
- NFCTypeNameFormatEmpty 空信息
- NFCTypeNameFormatMedia RFC 2046 定义的媒体类型
- NFCTypeNameFormatNFCExternal
- NFCTypeNameFormatNFCWellKnown
- NFCTypeNameFormatUnchanged
- NFCTypeNameFormatUnknown 未知
3.2 NFCNDEFMessage
//NFCNDEFPayload数组@property(nonatomic, copy) NSArray*records;复制代码
4. Errors
typedef NS_ERROR_ENUM(NFCErrorDomain, NFCReaderError) { NFCReaderErrorUnsupportedFeature = 1, //不支持此功能 NFCReaderErrorSecurityViolation, //安全问题 NFCReaderTransceiveErrorTagConnectionLost = 100,//标签连接丢失 NFCReaderTransceiveErrorRetryExceeded,//重连次数过多 NFCReaderTransceiveErrorTagResponseError,//标签响应错误 NFCReaderSessionInvalidationErrorUserCanceled = 200,//用户取消会话 NFCReaderSessionInvalidationErrorSessionTimeout,//会话时间超时 NFCReaderSessionInvalidationErrorSessionTerminatedUnexpectedly,//会话意外终止 NFCReaderSessionInvalidationErrorSystemIsBusy,//系统正忙,会话失败 NFCReaderSessionInvalidationErrorFirstNDEFTagRead,//读取的第一个NDEF NFCTagCommandConfigurationErrorInvalidParameters = 300,//标签配置无效参数};复制代码
三、注意事项
- 会话要求当前程序必须在前台运行,并且处于可视化界面
- 如果是程序处于后台或者不处于可视化界面,则停止扫描
- 每次扫描的限制时间为60秒,60秒后可再次初始化会话对象进行再次扫描
四、示例
1.配置开发证书
2.在TARGETS
>Capabilities
中打开Near Field Communication Tag Reading
3.在TARGETS
>Info
中配置NFC使用说明
4.代码逻辑
#import "ViewController.h"#import@interface ViewController () { NFCNDEFReaderSession *_session;}@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; //如果希望读取多个标签invalidateAfterFirstRead设置为No _session = [[NFCNDEFReaderSession alloc] initWithDelegate:self queue:nil invalidateAfterFirstRead:YES];}//开始扫描- (IBAction)startSession:(id)sender { [_session beginSession];}//结束扫描- (IBAction)endSession:(id)sender { [_session invalidateSession];}//扫描到的回调-(void)readerSession:(NFCNDEFReaderSession *)session didDetectNDEFs:(NSArray *)messages{}//错误回调-(void)readerSession:(NFCNDEFReaderSession *)session didInvalidateWithError:(NSError *)error{}@end复制代码