迟来的《Core NFC》
NFC技术是由非接触式射频识别(RFID)演变而来,由飞利浦半导体(现恩智浦半导体公司)、诺基亚和索尼共同研制开发,其基础是RFID及互连技术。...
介绍
从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根据文档显示,一次只能在系统中激活一个NFC NDEF会话,如果创建多个的话,系统会将其放在队列中,按照顺序执行
/* 初始化会话
* 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) id session;
//标签类型
@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 Reading3.在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
关注 Cocoa开发者社区
微信扫一扫关注公众号