迟来的《Core NFC》

1、介绍

NFC技术是由非接触式射频识别(RFID)演变而来,由飞利浦半导体(现恩智浦半导体公司)、诺基亚和索尼共同研制开发,其基础是RFID及互连技术。近场通讯(Near Field Communication,NFC)是一种短距高频的无线电技术,在13.56MHz频率运行于10厘米距离内。其传输速度有106 Kbit/秒、212 Kbit/秒或者424 Kbit/秒三种。api

从iPhone的历代机型配置中,能够看出在iPhone6及以上机型都拥有了支持NFC功能的固件,可是一直不开放给开发者使用,直到iOS11才开放仅有的具备读取NDEF格式的功能,而且须要iPhone7或者iPhone7 Plus才支持使用。数组

官方介绍,NFC有五种的类型,如图安全

2、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会话,若是建立多个的话,系统会将其放在队列中,按照顺序执行session

/* 初始化会话
 * delegate 会话的回调
 * queue 线程
 * invalidateAfterFirstRead 第一NDEF读取完毕后是否中止会话
 *
 * 当会话为读取多个NDEF时,每次读取成功都会经过代理回调
 * 读取多个NDEF时,会话会一直到调用终止活动API或者超时等才会中止会话
 *
 * 若是第一个NDEF读取成功便自动终止,这种状况下,经过readerSession:didInvalidateWithError:回调,此时状态为NFCReaderSessionInvalidationErrorFirstNDEFTagRead
 */
- (instancetype)initWithDelegate:(id<NFCNDEFReaderSessionDelegate>)delegate queue:(dispatch_queue_t)queue invalidateAfterFirstRead:(BOOL)invalidateAfterFirstRead;
//设备是否支持NFC读取标签
@property(class, nonatomic, readonly) BOOL readingAvailable;
//读取到信息时回调
- (void)readerSession:(NFCNDEFReaderSession *)session didDetectNDEFs:(NSArray<NFCNDEFMessage *> *)messages;

//发生错误或者无效时回调
- (void)readerSession:(NFCNDEFReaderSession *)session didInvalidateWithError:(NSError *)error;

2. 标签

2.1 NFCTag

//检测到的标签是否可用
@property(nonatomic, getter=isAvailable, readonly) BOOL available;

//获取会话
@property(nonatomic, weak, readonly) id<NFCReaderSession> 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定义的类型:ide

  • TypeNameFormatAbsoluteURI 统一使用资源标识标准
  • NFCTypeNameFormatEmpty 空信息
  • NFCTypeNameFormatMedia RFC 2046 定义的媒体类型
  • NFCTypeNameFormatNFCExternal
  • NFCTypeNameFormatNFCWellKnown
  • NFCTypeNameFormatUnchanged
  • NFCTypeNameFormatUnknown 未知

3.2 NFCNDEFMessage

//NFCNDEFPayload数组
@property(nonatomic, copy) NSArray<NFCNDEFPayload *> *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,//标签配置无效参数
};

3、注意事项

  • 会话要求当前程序必须在前台运行,而且处于可视化界面
  • 若是是程序处于后台或者不处于可视化界面,则中止扫描
  • 每次扫描的限制时间为60秒,60秒后可再次初始化会话对象进行再次扫描

4、示例

1.配置开发证书atom

2.在TARGETS>Capabilities中打开Near Field Communication Tag Readingspa

3.在TARGETS>Info中配置NFC使用说明线程

4.代码逻辑3d

#import "ViewController.h"
#import <CoreNFC/CoreNFC.h>

@interface ViewController ()<NFCNDEFReaderSessionDelegate>{
    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<NFCNDEFMessage *> *)messages{
    
}

//错误回调
-(void)readerSession:(NFCNDEFReaderSession *)session didInvalidateWithError:(NSError *)error{
    
}

@end
相关文章
相关标签/搜索