一:工程配置
(1)点击Capablity,选择Near Field Communication Tag Reading
截屏2020-12-29 10.34.47.png
(2)在info.plist中配置权限(Privacy - NFC Scan Usage Description)
截屏2020-12-29 10.36.30.png
(3)激活App ID的相关功能
aHR0cHM6Ly91cGxvYWQtaW1hZ2VzLmppYW5zaHUuaW8vdXBsb2FkX2ltYWdlcy85NjY5MjMtYTFlMjIzMjNlMzIzMjg1My5wbmc.png
二代码:
//
// NFCManager.h
// Runner
//
// Created by macmini on 2020/12/29.
//
#import <Foundation/Foundation.h>
#import <CoreNFC/CoreNFC.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSInteger, NFCSupportsStatus) {
NFCSupportStatusYes,//支持
NFCSupportStatusDeviceNo,//硬件不支持
NFCSupportStatusnSystemNo,//系统不支持
};
API_AVAILABLE(ios(11.0))
typedef void(^NFCScanSuccessBlock)(NFCNDEFMessage *message);
typedef void(^NFCScanErrorBlock)(NSError *error);
typedef void(^NFCWriteSuccessBlock)(void);
typedef void(^NFCWritErrorBlock)(NSError *error);
API_AVAILABLE(ios(11.0))
@interface NFCManager : NSObject
@property(nonatomic,copy)NFCScanSuccessBlock scanSuccessBlock;
@property(nonatomic,copy)NFCScanErrorBlock scanErrorBlock;
@property(nonatomic,copy)NFCWriteSuccessBlock writeSuccessBlock;
@property(nonatomic,copy)NFCWritErrorBlock writErrorBlock;
@property(nonatomic,assign) BOOL moreTag;//多标签识别
///单例
+ (instancetype)shareInstance;
///扫描
- (void)scanTagWithSuccessBlock:(NFCScanSuccessBlock)scanSuccessBlock andErrorBlock:(NFCScanErrorBlock)scanErrorBlock;
///获取扫描后的解析的结果
- (NSMutableArray *)getdataStr:(NFCNDEFMessage *)message;
///写入
- (void)writeMessage:(NFCNDEFMessage *)message ToTagWithSuccessBlock:(NFCWriteSuccessBlock)writeSuccessBlock andErrorBlock:(NFCWritErrorBlock)writErrorBlock;
///判断是否支持读功能
+ (NFCSupportsStatus)isSupportsNFCReading;
///判断是否支持写功能
+ (NFCSupportsStatus)isSupportsNFCWrite;
///获取类型名数组
+ (NSArray*)getNameFormatArray;
///获取类型名字
+ (NSString*)getNameFormat:(NFCTypeNameFormat)typeName;
///获取类型结构体
+ (NFCTypeNameFormat)getNFCTypeNameFormat:(NSString*)typeName;
@end
NS_ASSUME_NONNULL_END
//
// NFCManager.m
// Runner
//
// Created by macmini on 2020/12/29.
//
#import "NFCManager.h"
API_AVAILABLE(ios(11.0))
@interface NFCManager ()<NFCNDEFReaderSessionDelegate>{
BOOL isReading;
}
@property (strong, nonatomic) NFCNDEFReaderSession *session;
@property (strong, nonatomic) NFCNDEFMessage *message;
@end
@implementation NFCManager
#pragma mark - 单例
///强指针,应用结束才会死
static id _instance;
///外调单例方法
+ (instancetype)shareInstance
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [[self alloc] init];
});
return _instance;
}
///根本上只建立一个对象,只开辟一个内存
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = [super allocWithZone:zone];
});
return _instance;
}
///防止copy时,新建立一个对象,保证只开辟一个内存
- (id)copyWithZone:(nullable NSZone *)zone
{
return _instance;
}
#pragma mark - NFC
///扫描
- (void)scanTagWithSuccessBlock:(NFCScanSuccessBlock)scanSuccessBlock andErrorBlock:(NFCScanErrorBlock)scanErrorBlock{
self.scanSuccessBlock=scanSuccessBlock;
self.scanErrorBlock=scanErrorBlock;
isReading=YES;
[self beginScan];
}
///写入
- (void)writeMessage:(NFCNDEFMessage *)message ToTagWithSuccessBlock:(NFCWriteSuccessBlock)writeSuccessBlock andErrorBlock:(NFCWritErrorBlock)writErrorBlock{
self.message=message;
self.writeSuccessBlock=writeSuccessBlock;
self.writErrorBlock=writErrorBlock;
isReading=NO;
[self beginScan];
}
///判断是否支持读功能
+ (NFCSupportsStatus)isSupportsNFCReading{
if (@available(iOS 11.0,*)) {
if (NFCNDEFReaderSession.readingAvailable == YES) {
return NFCSupportStatusYes;
}
else{
NSLog(@"%@",@"该机型不支持NFC功能!");
return NFCSupportStatusDeviceNo;
}
}
else {
NSLog(@"%@",@"当前系统不支持NFC功能!");
return NFCSupportStatusnSystemNo;
}
}
///判断是否支持写功能
+ (NFCSupportsStatus)isSupportsNFCWrite{
if (@available(iOS 13.0,*)) {
if (NFCNDEFReaderSession.readingAvailable == YES) {
return NFCSupportStatusYes;
}
else{
NSLog(@"%@",@"该机型不支持NFC功能!");
return NFCSupportStatusDeviceNo;
}
}
else {
NSLog(@"%@",@"当前系统不支持NFC功能!");
return NFCSupportStatusnSystemNo;
}
}
///开始NFC
- (void)beginScan{
if (@available(iOS 11.0, *)) {
self.session = [[NFCNDEFReaderSession alloc]initWithDelegate:self queue:nil invalidateAfterFirstRead:NO];
self.session.alertMessage = @"准备扫描,请将卡片贴近手机";
[self.session beginSession];
}
}
///获取类型名数组
+ (NSArray*)getNameFormatArray{
return @[@"Empty",@"NFCWellKnown",@"Media",@"AbsoluteURI",@"NFCExternal",@"Unknown",@"Unchanged"];
}
///获取类型名字
+ (NSString*)getNameFormat:(NFCTypeNameFormat)typeName{
if (typeName==NFCTypeNameFormatEmpty) {
return @"Empty";
}
else if (typeName==NFCTypeNameFormatNFCWellKnown){
return @"NFCWellKnown";
}
else if (typeName==NFCTypeNameFormatMedia){
return @"Media";
}
else if (typeName==NFCTypeNameFormatAbsoluteURI){
return @"AbsoluteURI";
}
else if (typeName==NFCTypeNameFormatNFCExternal){
return @"NFCExternal";
}
else if (typeName==NFCTypeNameFormatUnknown){
return @"Unknown";
}
else if (typeName==NFCTypeNameFormatUnchanged){
return @"Unchanged";
}
return @"";
}
///获取类型结构体
+ (NFCTypeNameFormat)getNFCTypeNameFormat:(NSString*)typeName{
if ([typeName isEqualToString:@"Empty"]) {
return NFCTypeNameFormatEmpty;
}
else if ([typeName isEqualToString:@"NFCWellKnown"]){
return NFCTypeNameFormatNFCWellKnown;
}
else if ([typeName isEqualToString:@"Media"]){
return NFCTypeNameFormatMedia;
}
else if ([typeName isEqualToString:@"AbsoluteURI"]){
return NFCTypeNameFormatAbsoluteURI;
}
else if ([typeName isEqualToString:@"NFCExternal"]){
return NFCTypeNameFormatNFCExternal;
}
else if ([typeName isEqualToString:@"Unknown"]){
return NFCTypeNameFormatUnknown;
}
else if ([typeName isEqualToString:@"Unchanged"]){
return NFCTypeNameFormatUnchanged;
}
return NFCTypeNameFormatEmpty;
}
///createAMessage
- (NFCNDEFMessage*)createAMessage{
NSString* type = @"U";
NSData* typeData = [type dataUsingEncoding:NSUTF8StringEncoding];
NSString* identifier = @"12345678";
NSData* identifierData = [identifier dataUsingEncoding:NSUTF8StringEncoding];
NSString* payload1 = @"ahttps://www.baidu.com";
NSData* payloadData1 = [payload1 dataUsingEncoding:NSUTF8StringEncoding];
if (@available(iOS 13.0, *)) {
NFCNDEFPayload *NDEFPayload1=[[NFCNDEFPayload alloc]initWithFormat:NFCTypeNameFormatNFCWellKnown type:typeData identifier:identifierData payload:payloadData1];
NFCNDEFMessage* message = [[NFCNDEFMessage alloc]initWithNDEFRecords:@[NDEFPayload1]];
return message;
} else {
return nil;
}
}
///停止扫描
- (void)invalidateSession{
if (!self.moreTag) {
[self.session invalidateSession];
}
}
#pragma mark - NFC代理
///读取失败回调-读取成功后还是会回调这个方法
- (void)readerSession:(NFCNDEFReaderSession *)session didInvalidateWithError:(NSError *)error API_AVAILABLE(ios(11.0)){
NSLog(@"%@",error);
if (error.code == 201) {
NSLog(@"扫描超时");
}
if (error.code == 200) {
NSLog(@"取消扫描");
}
}
///读取成功回调iOS11-iOS12
- (void)readerSession:(NFCNDEFReaderSession *)session didDetectNDEFs:(NSArray*)messages
API_AVAILABLE(ios(11.0)){
dispatch_async(dispatch_get_main_queue(), ^{
if (self->isReading) {
if (@available(iOS 11.0, *)) {
for (NFCNDEFMessage *message in messages) {
session.alertMessage = @"读取成功";
[self invalidateSession];
if (self.scanSuccessBlock) {
self.scanSuccessBlock(message);
}
}
}
}
else{
//ios11-ios12下没有写入功能返回失败
session.alertMessage = @"写入失败";
[self invalidateSession];
}
});
}
///读取成功回调iOS13
- (void)readerSession:(NFCNDEFReaderSession *)session didDetectTags:(NSArray<__kindof id<NFCNDEFTag>> *)tags API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(watchos, macos, tvos){
dispatch_async(dispatch_get_main_queue(), ^{
if (tags.count>1) {
session.alertMessage=@"存在多个标签";
[session restartPolling];
return;
}
id tag=tags.firstObject;
[session connectToTag:tag completionHandler:^(NSError * _Nullable error) {
if (error) {
session.alertMessage = @"连接NFC标签失败";
[self invalidateSession];
return;
}
[tag queryNDEFStatusWithCompletionHandler:^(NFCNDEFStatus status, NSUInteger capacity, NSError * _Nullable error) {
if (error) {
session.alertMessage = @"查询NFC标签状态失败";
[self invalidateSession];
return;
}
if (status == NFCNDEFStatusNotSupported) {
session.alertMessage = @"标签不是NDEF格式";
[self invalidateSession];
return;
}
if (self->isReading) {
//读
[tag readNDEFWithCompletionHandler:^(NFCNDEFMessage * _Nullable message, NSError * _Nullable error) {
if (error) {
session.alertMessage = @"读取NFC标签失败";
[self invalidateSession];
}
else if (message==nil) {
session.alertMessage = @"NFC标签为空";
[self invalidateSession];
return;
}
else {
session.alertMessage = @"读取成功";
[self invalidateSession];
if (self.scanSuccessBlock) {
self.scanSuccessBlock(message);
}
}
}];
}
else{
//写数据
[tag writeNDEF:self.message completionHandler:^(NSError * _Nullable error) {
if (error) {
session.alertMessage = @"写入失败";
if (self.writErrorBlock) {
self.writErrorBlock(error);
}
}
else {
session.alertMessage = @"写入成功";
if (self.writeSuccessBlock) {
self.writeSuccessBlock();
}
}
[self invalidateSession];
}];
}
}];
}];
});
}
///
- (void)readerSessionDidBecomeActive:(NFCNDEFReaderSession *)session API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(watchos, macos, tvos){
}
///获取扫描后的解析的结果
- (NSMutableArray *)getdataStr:(NFCNDEFMessage *)message
{
NSMutableArray *mArr = [@[] mutableCopy];
for (NFCNDEFPayload *record in message.records) {
NSString *dataStr = [[NSString alloc] initWithData:record.payload encoding:NSUTF8StringEncoding];
NSLog(@"扫描结果 :%@", dataStr);
[mArr addObject:dataStr];
}
return mArr;
}
@end
网友评论