iOS開發(fā)-CoreNFC實現(xiàn)NFC標簽Tag讀取功能
一、NFC近場通信
近場通信(NFC)是一種無線通信技術(shù),它使設(shè)備能夠在不使用互聯(lián)網(wǎng)的情況下相互通信。它首先識別附近配備NFC的設(shè)備。NFC常用于智能手機和平板電腦。
二、實現(xiàn)NFC標簽Tag讀取功能
在iOS中提供了CoreNFC來實現(xiàn)NFC標簽Tag讀取功能。主要使用的類是NFCTagReaderSession。
NFCTagReaderSession配置讀取器會話的RF輪詢;可以將多個選項“或”運算在一起。此選項會影響可能的NFC標簽類型。同時需要實現(xiàn)delegate來實現(xiàn)掃描的回調(diào)。
NFCTagReaderSession初始化
if (@available(iOS 13.0, *)) {
if (NFCNDEFReaderSession.readingAvailable) {
self.tagSession = [[NFCTagReaderSession alloc]
initWithPollingOption:(NFCPollingISO14443 | NFCPollingISO15693 | NFCPollingISO15693) delegate:self queue:dispatch_get_main_queue()];
self.tagSession.alertMessage = @"讀取卡片,請將卡片靠近手機";
[self.tagSession beginSession]; //開始識別 彈出識別提示框
}else{
NSLog(@"NFC功能只支持iphone7以及iOS13.0以上設(shè)備");
}
}else{
NSLog(@"NFC功能只支持iphone7以及iOS13.0以上設(shè)備");
}
NFCNDEFReaderSessionDelegate的相關(guān)方法
- 識別結(jié)果的回調(diào)
-(void)readerSession:(NFCNDEFReaderSession *)session didDetectNDEFs:(NSArray<NFCNDEFMessage *> *)messages API_AVAILABLE(ios(11.0))
- 錯誤回調(diào)
-(void)readerSession:(NFCNDEFReaderSession *)session didInvalidateWithError:(NSError *)error API_AVAILABLE(ios(11.0))
- 在Session無效時調(diào)用
- (void)tagReaderSession:(NFCTagReaderSession *)session didInvalidateWithError:(NSError *)error API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(watchos, macos, tvos)
- 當NFC讀取器會話變?yōu)锳ctive時調(diào)用
- (void)tagReaderSessionDidBecomeActive:(NFCTagReaderSession *)session API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(watchos, macos, tvos)
- 當讀取器在輪詢序列中檢測到NFC標記時調(diào)用
- (void)tagReaderSession:(NFCTagReaderSession *)session didDetectTags:(NSArray<__kindof id> *)tags API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(watchos, macos, tvos)
實現(xiàn)識別NFC標簽Tag完整代碼如下
#import "INNFCExampleViewController.h"
#import <CoreNFC/CoreNFC.h>
API_AVAILABLE(ios(11.0))
@interface INNFCExampleViewController ()<NFCNDEFReaderSessionDelegate, NFCTagReaderSessionDelegate>
@property (nonatomic, strong) NFCNDEFReaderSession *session;
@property (nonatomic, strong) NFCTagReaderSession *tagSession;
@property (nonatomic, strong) id<NFCMiFareTag> currentTag;
@property (nonatomic, strong) UILabel *showLabel;
@end
@implementation INNFCExampleViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor whiteColor];
UIButton *startQueryBtn;
startQueryBtn = [UIButton buttonWithType:UIButtonTypeCustom];
startQueryBtn.frame = CGRectMake(50, 100, 60, 36);
startQueryBtn.layer.cornerRadius = 4;
startQueryBtn.backgroundColor = [UIColor brownColor];
[startQueryBtn setTitle:@"開始識別" forState:UIControlStateNormal];
[startQueryBtn addTarget:self action:@selector(startQueryBtnClick) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:startQueryBtn];
UIButton *endQueryBtn;
endQueryBtn = [UIButton buttonWithType:UIButtonTypeCustom];
endQueryBtn.frame = CGRectMake(250, 100, 60, 36);
endQueryBtn.layer.cornerRadius = 4;
endQueryBtn.backgroundColor = [UIColor brownColor];
[endQueryBtn setTitle:@"結(jié)束識別" forState:UIControlStateNormal];
[endQueryBtn addTarget:self action:@selector(endQueryBtnClick) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:endQueryBtn];
}
- (void)startQueryBtnClick {
if (@available(iOS 13.0, *)) {
if (NFCNDEFReaderSession.readingAvailable) {
self.tagSession = [[NFCTagReaderSession alloc]
initWithPollingOption:(NFCPollingISO14443 | NFCPollingISO15693 | NFCPollingISO15693) delegate:self queue:dispatch_get_main_queue()];
self.tagSession.alertMessage = @"讀取卡片,請將卡片靠近手機";
[self.tagSession beginSession]; //開始識別 彈出識別提示框
}else{
NSLog(@"NFC功能只支持iphone7以及iOS13.0以上設(shè)備");
}
}else{
NSLog(@"NFC功能只支持iphone7以及iOS13.0以上設(shè)備");
}
/**
//如果希望讀取多個標簽invalidateAfterFirstRead設(shè)置為NO
if (@available(iOS 11.0, *)) {
__weak typeof(self) weakSelf = self;
self.session = [[NFCNDEFReaderSession alloc] initWithDelegate:weakSelf queue:dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT) invalidateAfterFirstRead:YES];
[self.session beginSession];
} else {
// Fallback on earlier versions
}
*/
}
- (void)endQueryBtnClick {
/**
if (@available(iOS 11.0, *)) {
[self.session invalidateSession];
} else {
// Fallback on earlier versions
}
*/
}
#pragma mark -- <NFCNDEFReaderSessionDelegate>
//掃描到的回調(diào)
-(void)readerSession:(NFCNDEFReaderSession *)session didDetectNDEFs:(NSArray<NFCNDEFMessage *> *)messages API_AVAILABLE(ios(11.0)){
for (NFCNDEFMessage *message in messages) {
for (NFCNDEFPayload *payload in message.records) {
NSLog(@"readerSession payload data = %@", payload.payload);
NSString *str = [[NSString alloc] initWithData:payload.payload encoding:NSUTF8StringEncoding];
//回到主線程
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"readerSession str:%@",str);
});
}
}
}
//錯誤回調(diào)
-(void)readerSession:(NFCNDEFReaderSession *)session didInvalidateWithError:(NSError *)error API_AVAILABLE(ios(11.0)){
NSLog(@"readerSession didInvalidateWithError error:%@", error);
}
#pragma mark -- NFCTagReaderSessionDelegate
/*!
* @method tagReaderSession:didInvalidateWithError:
*
* @param session The session object that is invalidated.
* @param error The error indicates the invalidation reason.
*
* @discussion Gets called when a session becomes invalid. At this point the client is expected to discard
* the returned session object.
*/
- (void)tagReaderSession:(NFCTagReaderSession *)session didInvalidateWithError:(NSError *)error API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(watchos, macos, tvos) {
NSLog(@"tagReaderSession didInvalidateWithError error:%@", error);
if (error.code == 200) {
return;
}
[session invalidateSession];
}
/*!
* @method tagReaderSessionDidBecomeActive:
*
* @param session The session object in the active state.
*
* @discussion Gets called when the NFC reader session has become active. RF is enabled and reader is scanning for tags.
* The @link readerSession:didDetectTags: @link/ will be called when a tag is detected.
*/
- (void)tagReaderSessionDidBecomeActive:(NFCTagReaderSession *)session API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(watchos, macos, tvos) {
NSLog(@"tagReaderSession tagReaderSessionDidBecomeActive");
}
/*!
* @method tagReaderSession:didDetectTags:
*
* @param session The session object used for tag detection.
* @param tags Array of @link NFCTag @link/ objects.
*
* @discussion Gets called when the reader detects NFC tag(s) in the polling sequence.
*/
- (void)tagReaderSession:(NFCTagReaderSession *)session didDetectTags:(NSArray<__kindof id<NFCTag>> *)tags API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(watchos, macos, tvos) {
_currentTag = [tags firstObject];
NSData *data ;
if (self.currentTag.type == NFCTagTypeMiFare) {
id<NFCMiFareTag> mifareTag = [self.currentTag asNFCMiFareTag];
data = mifareTag.identifier;
}else if (self.currentTag.type == NFCTagTypeISO15693){
id<NFCISO15693Tag> mifareTag = [self.currentTag asNFCISO15693Tag];
data = mifareTag.identifier;
}else if (self.currentTag.type == NFCTagTypeISO15693){
id<NFCISO15693Tag> mifareTag = [self.currentTag asNFCISO15693Tag];
data = mifareTag.identifier;
}else{
NSLog(@"未識別出NFC格式");
}
NSString *str = [self convertDataBytesToHex:data];
NSLog(@"tagReaderSession didDetectTags str:%@", str);
//識別成功處理
[session invalidateSession];
}
- (NSString *)convertDataBytesToHex:(NSData *)dataBytes {
if (!dataBytes || [dataBytes length] == 0) {
return @"";
}
NSMutableString *hexStr = [[NSMutableString alloc] initWithCapacity:[dataBytes length]];
[dataBytes enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) {
unsigned char *dataBytes = (unsigned char *)bytes;
for (NSInteger i = 0; i < byteRange.length; i ++) {
NSString *singleHexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) & 0xff];
if ([singleHexStr length] == 2) {
[hexStr appendString:singleHexStr];
} else {
[hexStr appendFormat:@"0%@", singleHexStr];
}
}
}];
return hexStr;
}
@end
至此,NFC標簽Tag讀取功能代碼完成。
三、小結(jié)
iOS開發(fā)-CoreNFC實現(xiàn)NFC標簽Tag讀取功能文章來源:http://www.zghlxwxcb.cn/news/detail-733483.html
學(xué)習(xí)記錄,每天不停進步。文章來源地址http://www.zghlxwxcb.cn/news/detail-733483.html
到了這里,關(guān)于iOS開發(fā)-CoreNFC實現(xiàn)NFC標簽Tag讀取功能的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!