iOS NFC开发(读标签与写标签)

news/2024/10/18 6:08:51/

#一.说明
1-苹果手机从iPhone6开始装有NFC硬件,但并未对第三方应用开放。因此iPhone6及iPhone6s不能识别NFC标签,但是可以使用系统NFC功能如:刷地铁。
2-苹果从iOS11系统开始开放NFC读取功能,同时要求iPhone7及以上机型。不满足要求则无法读取NFC标签
3-苹果在iOS13系统开放了标签写入功能,想要向标签内写入数据,需要升级系统到iOS13,同样只能写入DNEF格式数据
4-另外苹果只开放DNEF数据格式的NFC标签读取,如果数据格式不满足则无法读取。身份证、地铁卡、银行卡、大部分的工卡都不是DNEF格式,因此无法读取。(空标签只能在iOS13系统下才可以读取到)(NFC标签可以去淘宝购买,价格很便宜 9.9六个还包邮)
5-身份证、地铁卡虽然无法读取到数据,但是可以用苹果官方APP“快捷指令”进行标记,来实现一些新颖玩法(需要iPhoneXS以上机型)
6-关于后台读取,iPhoneXS以上机型支持,屏幕点亮状态下(无需解锁),手机可以读取一些特定数据格式的NFC标签。识别到标签后,可以实现拨打电话,发送邮件等功能(需解锁)
#二.项目推荐
我自己写的一个关于NFC读写的APP,可以直接用来调试NFC标签
https://itunes.apple.com/cn/app/id1492298987
#三.工程配置
1.需要配置Capabilitles。使用NFC需要配置Capabilitles,这会自动为你生成entitlements文件中的必要配置。
图一
2.打开隐私相关设置。向info.plist中添加Privacy - NFC Scan Usage Description。
图二
3.激活App ID的相关功能。如下图所示(自动签名项目系统会自动配置)
图三
#四.代码
1.NFCManager.h

#import <Foundation/Foundation.h>
#import <CoreNFC/CoreNFC.h>NS_ASSUME_NONNULL_BEGINtypedef 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;//多标签识别+(NFCManager *)sharedInstance;
-(void)scanTagWithSuccessBlock:(NFCScanSuccessBlock)scanSuccessBlock andErrorBlock:(NFCScanErrorBlock)scanErrorBlock;
-(void)writeMessage:(NFCNDEFMessage *)message ToTagWithSuccessBlock:(NFCWriteSuccessBlock)writeSuccessBlock andErrorBlock:(NFCWritErrorBlock)writErrorBlock;
//判断是否支持读写功能
+(NFCSupportsStatus)isSupportsNFCReading;
+(NFCSupportsStatus)isSupportsNFCWrite;
//获取类型名数组
+(NSArray*)getNameFormatArray;
//获取类型名字
+(NSString*)getNameFormat:(NFCTypeNameFormat)typeName;
//获取类型结构体
+(NFCTypeNameFormat)getNFCTypeNameFormat:(NSString*)typeName;
@endNS_ASSUME_NONNULL_END

1.NFCManager.m

#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 - 单例方法
+(NFCManager *)sharedInstance{static dispatch_once_t onceToken;static NFCManager * sSharedInstance;dispatch_once(&onceToken, ^{sSharedInstance = [[NFCManager alloc] init];});return sSharedInstance;
}
-(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;}
}
-(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;
}
-(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 - NFCNDEFReaderSessionDelegate
//读取失败回调-读取成功后还是会回调这个方法
- (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){}
@end

http://www.ppmy.cn/news/465042.html

相关文章

Android中NFC标签卡的读取

前几天老大把一张卡拿给我说要我把用NFC技术读出它的uid来&#xff0c;写成一个demo给他&#xff0c;我第一反应就是一脸闷逼&#xff0c;可是卡已经交给我了&#xff0c;只能照办不误了&#xff01;在我不长的开发生涯中是从来没有接触过NFC的&#xff0c;所以在接到任务后&am…

android 苹果支付,不仅应用于支付 手机上的NFC功能解析

对于NFC功能大家都已经比较熟悉&#xff0c;在之前就已经有手机配备NFC功能。此前北京移动还联合一卡通推出过NFC-SIM卡&#xff0c;可以让手机作为北京市政一卡通来使用。而在去年苹果推出Apple Pay之后&#xff0c;NFC功能俨然成为了手机支付必不可少的环节&#xff0c;在未来…

NFC 协议简介

NFC技术标准 NFC标准兼容飞利浦的 Mifare 标准(ISO 14443 A&#xff0c;B)&#xff0c;以及索尼公司的FeliCa 标准&#xff0c;其中TypeA&#xff0c;TypeB为Mifare标准&#xff0c;F为Felica标准。 特性说明频段13.56 MHz通讯距离约10厘米传输速度106kbps、212kbps、424kbps…

苹果7pnfc功能门禁卡_苹果NFC功能不再鸡肋?原来还能这么玩,内附门禁卡复制教程...

安卓手机用户NFC功能发展越来越好&#xff0c;很多功能以及涉及到我们日常生活&#xff0c;乘公交、门禁卡等。而苹果早在iPhone 6S的时候就开始搭载NFC功能&#xff0c;却只能实现Apple pay支付功能&#xff0c;且使用程度不高。 对于用户反馈&#xff0c;苹果于去年逐渐开放部…

android nfc读写demo,android nfc常用标签读取总结

有几天没有更新博客了,不过本篇却准备了许久,希望能带给每一位开发者最简单高效的学习方式。废话到此为止,下面开始正文。 NFC(Near Field Communication,近场通信)是一种数据传输技术。与Wi-Fi、蓝牙、红外线等数据传输技术的一个主要差异就是有效距离一般不能超过4厘米。…

屏幕录制没有声音?快看看这2个方法!

案例&#xff1a;我今天尝试在电脑上进行屏幕录制&#xff0c;一开始一切都挺正常的。直到结束后&#xff0c;查看刚刚录制的视频发现没有声音。 【录屏只有画面没有声音&#xff0c;会影响视频的观感体验&#xff0c;甚至你根本不知道视频想表达的意思。那录屏的同时如何录制…

机器学习与深度学习——基于潜在语义分析(LSA)的文档相似度计算

机器学习与深度学习——基于潜在语义分析&#xff08;LSA&#xff09;的文档相似度计算 基于潜在语义分析&#xff08;LSA&#xff09;是一种使用数学和统计方法来分析文本数据的技术。该技术可用于发现文本之间的关系&#xff0c;以及为文本提供有关其含义的更深层次的信息。…

AI生成--git 常用命令

git init&#xff1a;初始化Git仓库git clone&#xff1a;克隆Git仓库git add&#xff1a;将文件添加到暂存区git commit&#xff1a;将暂存区的文件提交到本地仓库git push&#xff1a;将本地仓库的文件推送到远程仓库git pull&#xff1a;从远程仓库拉取代码到本地git status…