Use of NFC developed by IOS

Time:2022-5-25

1、 Understanding NFC
In fact, the official documents on the use of NFC in IOS development have been very detailed. First go to the official documents:
Document address:https://developer.apple.com/documentation/corenfc?language=objc
NFC enabled devices:
1. The mobile phone on IOS 11 only supports the function of reading, and you can read labels through the NFC function of the mobile phone
2. The system above ios13 supports the write function.
3. The minimum devices that support NFC are iPhone 7 and iPhone 7plus

2、 Read NFC tag nDef
NDef refers to NFC data exchange format: NFC data exchange format, which is the data format in NFC tag agreed by NFC organization.
NDef is a lightweight, compact binary format with various data types defined by URL, vCard and NFC.
NDef is composed of various data records, and each record is composed of header and payload. The data type and size of nDef record are indicated by the header of recording load. The header here includes three parts, namely length, type and identifier.
NFC data exchange format: NFC data exchange format, which is the data format in NFC tag agreed by NFC organization.
For details, please refer to:https://blog.csdn.net/vampire_armand/article/details/39372953
1. Import header file
object-c

#import <CoreNFC/CoreNFC.h>

swift

import CoreNFC

2. Read NFC in nDef format
2.1 local configuration
Refer to official documents:https://developer.apple.com/documentation/corenfc/adding_support_for_background_tag_reading
2.1.1 open the permission to read NFC tags. After Xcode opens the permission, it will be automatically synchronized to the developer’s appid

Use of NFC developed by IOS

image.png
Use of NFC developed by IOS

image.png

Simultaneous generation Entitlements file

Use of NFC developed by IOS

image.png

2.1.2 add permission description
Privacy – NFC Scan Usage Description
String

Use of NFC developed by IOS

image.png

Official demo address
[Building an NFC Tag-Reader App] Read NFC tags with NDEF messages in your app.
https://developer.apple.com/documentation/corenfc/building_an_nfc_tag-reader_app?language=objc(used to scan NFC in nDef format. Ios11-ios12 are read-only and cannot be written. Ios13 can be read and written in the future)
code

#import <Foundation/Foundation.h>
#import <CoreNFC/CoreNFC.h>

NS_ASSUME_NONNULL_BEGIN

typedef NS_ENUM(NSInteger, NFCSupportsStatus) {
    Nfcsupportstatusyes, // Yes
    Nfcsupportstatusdeviceno, // not supported by hardware
    Nfcsupportstatusnsystemno, // not supported by the system
};

API_AVAILABLE(ios(11.0))
typedef void(^NFCScanSuccessBlock)(NFCNDEFMessage *message);
typedef void(^NFCScanErrorBlock)(NSError *error);
API_AVAILABLE(ios(13.0))
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;

+(NFCManager *)sharedInstance;

//Judge whether the read-write function is supported
+(NFCSupportsStatus)isSupportsNFCReading;
-(void)scanTagWithSuccessBlock:(NFCScanSuccessBlock)scanSuccessBlock andErrorBlock:(NFCScanErrorBlock)scanErrorBlock;

@end

NS_ASSUME_NONNULL_END
#import "NFCManager.h"


@interface NFCManager()<NFCNDEFReaderSessionDelegate>{
    BOOL isReading;
}

@property (strong, nonatomic) NFCNDEFReaderSession *session;

@property (strong, nonatomic) NFCNDEFMessage *message;

@end
@implementation NFCManager

#Pragma mark - single case method
+(NFCManager *)sharedInstance{
    static dispatch_once_t onceToken;
    static NFCManager * sSharedInstance;
    dispatch_once(&onceToken, ^{
        sSharedInstance = [[NFCManager alloc] init];
    });
    return sSharedInstance;
}

+(NFCSupportsStatus)isSupportsNFCReading{
    if (@available(iOS 11.0,*)) {
        if (NFCNDEFReaderSession.readingAvailable == YES) {
            return NFCSupportStatusYes;
        }
        else{
            Nslog (@ '% @', @ 'this model does not support NFC function!');
            return NFCSupportStatusDeviceNo;
        }
    }
    else {
        Nslog (@ '% @', @ 'the current system does not support NFC function!');
        return NFCSupportStatusnSystemNo;
    }
}


-(void)scanTagWithSuccessBlock:(NFCScanSuccessBlock)scanSuccessBlock andErrorBlock:(NFCScanErrorBlock)scanErrorBlock{
    self.scanSuccessBlock=scanSuccessBlock;
    self.scanErrorBlock=scanErrorBlock;
    isReading=YES;
    [self beginScan];
}


-(void)beginScan{
    if (@available(iOS 11.0, *)) {
        self.session = [[NFCNDEFReaderSession alloc]initWithDelegate:self queue:nil invalidateAfterFirstRead:NO];
        self. session. Alertmessage = @ "ready to scan, please put the card close to your mobile phone";
        [self.session beginSession];
    }
}

//Stop scanning
-(void)invalidateSession{
        [self.session invalidateSession];

}

#pragma mark - NFCNDEFReaderSessionDelegate
//Read failure callback - this method will still be called back after successful reading
- (void)readerSession:(NFCNDEFReaderSession *)session didInvalidateWithError:(NSError *)error API_AVAILABLE(ios(11.0)){
    NSLog(@"%@",error);
    if (error.code == 201) {
        Nslog (@ "scan timeout");
    }
    if (error.code == 200) {
        Nslog (@ "cancel scan");
    }
}

//Read success callback 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 = @ "read successfully";
                    [self invalidateSession];
                    if (self.scanSuccessBlock) {
                        self.scanSuccessBlock(message);
                    }
                }
            }
        }
        else{
            //There is no write function under ios11-ios12. Return failure
            session. Alertmessage = @ "read failed";
            [self invalidateSession];
        }
        
    });
}

//Read successful callback 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 = @ "there are multiple tags";
            [session restartPolling];
            return;
        }
        id  tag=tags.firstObject;
        [session connectToTag:tag completionHandler:^(NSError * _Nullable error) {
            if (error) {
                session. Alertmessage = @ "failed to connect NFC tag";
                [self invalidateSession];
                return;
            }
            [tag queryNDEFStatusWithCompletionHandler:^(NFCNDEFStatus status, NSUInteger capacity, NSError * _Nullable error) {
                if (error) {
                    session. Alertmessage = @ "failed to query NFC tag status";
                    [self invalidateSession];
                    return;
                }
                if (status == NFCNDEFStatusNotSupported) {
                    session. Alertmessage = @ "label is not in nDef format";
                    [self invalidateSession];
                    return;
                }
                if (self->isReading) {
                    //Read
                    [tag readNDEFWithCompletionHandler:^(NFCNDEFMessage * _Nullable message, NSError * _Nullable error) {
                        if (error) {
                            session. Alertmessage = @ "failed to read NFC tag";
                            [self invalidateSession];
                        }
                        else if (message==nil) {
                            session. Alertmessage = @ "NFC tag is empty";
                            [self invalidateSession];
                            return;
                        }
                        else {
                            session. Alertmessage = @ "read successfully";
                            [self invalidateSession];
                            if (self.scanSuccessBlock) {
                                self.scanSuccessBlock(message);
                            }
                        }
                    }];
                }
                else{
                    //Write data
                    [tag writeNDEF:self.message completionHandler:^(NSError * _Nullable error) {
                        if (error) {
                            session. Alertmessage = @ "write failed";
                            if (self.writErrorBlock) {
                                self.writErrorBlock(error);
                            }
                        }
                        else {
                            session. Alertmessage = @ "write succeeded";
                            if (self.writeSuccessBlock) {
                                self.writeSuccessBlock();
                            }
                        }
                        [self invalidateSession];
                    }];
                }
            }];
        }];
    });
}

- (void)readerSessionDidBecomeActive:(NFCNDEFReaderSession *)session API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(watchos, macos, tvOS){
    
}
@end

3. Read tagged NFC
[Creating NFC Tags from Your iPhone] Save data to tags, and interact with them using native tag protocols.
https://developer.apple.com/documentation/corenfc/creating_nfc_tags_from_your_iphone(NFC such as iso15693, ISO7816, felica and Mifare can be scanned, and can be read and written, but there must be aid)
3.1 it needs to be in info Add the corresponding tag in plist, the tag is an array, and add the aid of the adapted NFC

Use of NFC developed by IOS

image.png

Note: in swift project, if a tag is not used, info Plist should not be added. Do not bring this tag during initialization. If info Plist has added this tag. You must add aid, otherwise you will not be able to evoke the pages scanned by NFC.
3.2 code
object-c
NFCManager.h

#import <Foundation/Foundation.h>
#import <CoreNFC/CoreNFC.h>


NS_ASSUME_NONNULL_BEGIN

typedef NS_ENUM(NSInteger, NFCSupportsStatus) {
    Nfcsupportstatusyes, // Yes
    Nfcsupportstatusdeviceno, // not supported by hardware
    Nfcsupportstatusnsystemno, // not supported by the system
};

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;// Multi label recognition




+(NFCManager *)sharedInstance;
-(void)scanTagWithSuccessBlock:(NFCScanSuccessBlock)scanSuccessBlock andErrorBlock:(NFCScanErrorBlock)scanErrorBlock;
-(void)writeMessage:(NFCNDEFMessage *)message ToTagWithSuccessBlock:(NFCWriteSuccessBlock)writeSuccessBlock andErrorBlock:(NFCWritErrorBlock)writErrorBlock;
//Judge whether the read-write function is supported
+(NFCSupportsStatus)isSupportsNFCReading;
+(NFCSupportsStatus)isSupportsNFCWrite;

@end

NS_ASSUME_NONNULL_END

NFCManager.m

#import "NFCManager.h"

@interface NFCManager ()<NFCTagReaderSessionDelegate>{
    BOOL isReading;
}

@property (strong, nonatomic) NFCTagReaderSession *tagReaderSession;

@property (strong, nonatomic) NFCNDEFMessage *message;

@property(nonatomic,weak)id<NFCISO7816Tag> currentTag;

@end

@implementation NFCManager

#Pragma mark - single case method
+(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 (@ '% @', @ 'this model does not support NFC function!');
            return NFCSupportStatusDeviceNo;
        }
    }
    else {
        Nslog (@ '% @', @ 'the current system does not support NFC function!');
        return NFCSupportStatusnSystemNo;
    }
}
+(NFCSupportsStatus)isSupportsNFCWrite{
    if (@available(iOS 13.0,*)) {
        if (NFCNDEFReaderSession.readingAvailable == YES) {
            return NFCSupportStatusYes;
        }
        else{
            Nslog (@ '% @', @ 'this model does not support NFC function!');
            return NFCSupportStatusDeviceNo;
        }
    }
    else {
        Nslog (@ '% @', @ 'the current system does not support NFC function!');
        return NFCSupportStatusnSystemNo;
    }
}
-(void)beginScan{
    if (@available(iOS 11.0, *)) {
        self.tagReaderSession = [[NFCTagReaderSession alloc]initWithPollingOption:NFCPollingISO14443 delegate:self queue:dispatch_queue_create("beckhams",DISPATCH_QUEUE_SERIAL)];
        self.tagReaderSession.alertMessage = @"message";
            [self.tagReaderSession beginSession];
        
    }
}


-(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;
    }
}

//Stop scanning
-(void)invalidateSession{
    [self.tagReaderSession invalidateSession];
}




- (void)tagReaderSession:(NFCTagReaderSession *)session didDetectTags:(NSArray<__kindof id<NFCTag>> *)tags API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(watchos, macos, tvos){
    if (tags.count > 1){
        Nslog (@ "card reading error");
        return;
    }
    
    
    id<NFCISO7816Tag> Tag7816 = [tags.firstObject asNFCISO7816Tag];
    //The tag7816 instance here is an object for sending instructions later.
    if (Tag7816 == nil){
        Nslog (@ "non 7816 card read");
        return;
    }
    //The aid obtained here is the first step in info The ID (a000000000) set in plist is generally provided by the card dealer and represents the application representation of the card.
    NSLog(@"Tag7816.initialSelectedAID:%@",Tag7816.initialSelectedAID);
    __weak typeof(self) weakSelf = self;
    [self.tagReaderSession connectToTag:Tag7816 completionHandler:^(NSError * _Nullable error) {
        __strong typeof(weakSelf) strongSelf = weakSelf;
        if (error){
            NSLog(@"TconnectToTag:%@",error);
            return;
        }
        self.currentTag = Tag7816;
        self. tagReaderSession. Alertmessage = @ "NFC recognized";
        //Here you can start executing instructions and interacting with the CPU card.
        [self sendApduSingle:@"00A400000112501"];// Hexadecimal instruction

        
    }];
}
//Example code of sending instruction:
-(void)sendApduSingle:(NSString *)apduStr{
    //Apdustr is the command string sent, such as 00a5030004b000000033434561
    NSData *apduData = [self convertHexStrToData:apduStr]; //  Convert instructions to data format
    NFCISO7816APDU *cmd = [[NFCISO7816APDU alloc]initWithData:apduData];  //  Initialize nfciso7816apdu.
    
    __block NSData *recvData = nil;
    __block NSError *lerror = nil;
    __block BOOL bRecv = NO;
    __block int lsw = 0;
    NSLog(@"send data => %@", apduData);
    
    //The tag7816 here is the tag obtained in the above agreement
    [self.currentTag sendCommandAPDU:cmd completionHandler:^(NSData * _Nonnull responseData, uint8_t sw1, uint8_t sw2, NSError * _Nullable error) {
        NSLog(@"------resp:%@ sw:%02x%02x  error:%@", responseData, sw1, sw2, error);
        Nslog (@ "responsedata hex:% @", [self convertapdulistdatatohexstr: responsedata]);
        lerror = error;
        lsw = sw1;
        lsw = (lsw << 8) | sw2;
        if (responseData) {
            recvData = [[NSData alloc]initWithData:responseData];
        }
        //Get the returned data and write the code according to the specific business needs....
        [self invalidateSession];
    }];
}


//Convert string to nsdata
- (NSData *)convertHexStrToData:(NSString *)str {
    if (!str || [str length] == 0) {
        return nil;
    }
    
    NSMutableData *hexData = [[NSMutableData alloc] initWithCapacity:8];
    NSRange range;
    if ([str length] % 2 == 0) {
        range = NSMakeRange(0, 2);
    } else {
        range = NSMakeRange(0, 1);
    }
    for (NSInteger i = range.location; i < [str length]; i += 2) {
        unsigned int anInt;
        NSString *hexCharStr = [str substringWithRange:range];
        NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr];
        
        [scanner scanHexInt:&anInt];
        NSData *entity = [[NSData alloc] initWithBytes:&anInt length:1];
        [hexData appendData:entity];
        
        range.location += range.length;
        range.length = 2;
    }
    return hexData;
}


//Nsdata to string
-(NSString *)convertApduListDataToHexStr:(NSData *)data{
        if (!data || [data length] == 0) {
            return @"";
        }
        NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[data length]];
        [data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) {
            unsigned char *dataBytes = (unsigned char*)bytes;
            for (NSInteger i = 0; i < byteRange.length; i++) {
                NSString *hexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) & 0xff];
                if ([hexStr length] == 2) {
                        [string appendString:hexStr];
                } else {
                    [string appendFormat:@"0%@", hexStr];
                }
            }
        }];
        return [string uppercaseString];
}

- (void)tagReaderSession:(NFCTagReaderSession *)session didInvalidateWithError:(NSError *)error API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(watchos, macos, tvos){
    NSLog(@"%@",error);
}


@end

Swift

import UIKit
import CoreNFC

class SwiftNFCManager: NSObject ,NFCTagReaderSessionDelegate{
    enum NFCSupportsStatus : NSInteger {
        Case nfcsupportstatusyes = 0 // supported
        Case nfcsupportstatusdeviceno = 1 // not supported by hardware
        Case nfcsupportstatusnsystemno = 2 // not supported by the system
    }
    typealias  block = (Data,Bool) -> Void
    var completeHandle:block?
    typealias  NFCScanSuccessBlock = (String) -> Void
    typealias  NFCScanErrorBlock = (String) -> Void
    var delegate:NfcProtocol?
    var isReading:Bool?
    var scanSuccessBlock:NFCScanSuccessBlock?
    var scanErrorBlock:NFCScanErrorBlock?
    var tagSession:NFCTagReaderSession?
    var currentTag:NFCISO7816Tag?
    static let shared = SwiftNFCManager()
    
    class func isSupportsNFCReading()->NFCSupportsStatus{
        if #available(iOS 11.0, *){
            if NFCNDEFReaderSession.readingAvailable == true{
                return NFCSupportsStatus.NFCSupportStatusYes
            }else{
                Print ("this model does not support NFC function!")
                return NFCSupportsStatus.NFCSupportStatusDeviceNo
            }
        }else{
            Print ("the current system does not support NFC function!")
            return NFCSupportsStatus.NFCSupportStatusnSystemNo
        }
    }
    class func isSupportsNFCWrite()->NFCSupportsStatus{
        if #available(iOS 13.0, *){
            if NFCNDEFReaderSession.readingAvailable == true{
                return NFCSupportsStatus.NFCSupportStatusYes
            }else{
                Print ("this model does not support NFC function!")
                return NFCSupportsStatus.NFCSupportStatusDeviceNo
            }
        }else{
            Print ("the current system does not support NFC write function!")
            return NFCSupportsStatus.NFCSupportStatusnSystemNo
        }
    }
    func startScanNFC(successBlock:@escaping NFCScanSuccessBlock,errorBlock:@escaping NFCScanErrorBlock) {
        scanSuccessBlock = successBlock
        scanErrorBlock = errorBlock
        isReading = true
        self.beginScan()
    }
    func beginScan() {
        if #available(iOS 11.0, *){
            tagSession = NFCTagReaderSession(pollingOption: [.iso14443, .iso15693, .iso18092], delegate: self, queue: nil)
            tagSession?.alertMessage = "Hold your iPhone near an NFC Type 2 tag."
               tagSession?.begin()
        }
    }
    //Stop scanning
    func invalidateSession() {
        self.tagSession?.invalidate()
    }
    
    
    //MARK: NFCTagReaderSessionDelegate
     
     func tagReaderSessionDidBecomeActive(_ session: NFCTagReaderSession) {
         print("tagReaderSessionDidBecomeActive")
     }
     
     func tagReaderSession(_ session: NFCTagReaderSession, didInvalidateWithError error: Error) {
         scanErrorBlock! ("scan NFC failed")
         print("error:\(error)")
     }
     
     func tagReaderSession(_ session: NFCTagReaderSession, didDetect tags: [NFCTag]) {
         
         if tags.count > 1 {
             Print ("card reading error")
             scanErrorBlock! ("card reading error")
             session.alertMessage = "More than 1 tags was found. Please present only 1 tag."
             return
         }
         
         
         let Tag7816:NFCTag = tags.first!
         switch Tag7816 {
         case .feliCa(_):
             print("NFCFeliCaTag")
         case let .iso7816(tag):
             //The aid obtained here is the first step in info The ID (a000000000) set in plist is generally provided by the card dealer and represents the application representation of the card.
             self.tagSession?.connect(to: Tag7816, completionHandler: {[weak self] (error) in
                 if error != nil {
                     print("TconnectToTag:\(String(describing: error))")
                     session.invalidate(errorMessage: "Connection error. Please try again.")
                     self?.delegate?.connectNfcError()
                     return
                 }
                 self?.delegate?.connectNfcSuccess()
                 self?.currentTag = tag
                 self?. tagSession?. Alertmessage = "NFC has been recognized"
                 self?.invalidateSession()
             })
         case .iso15693(_):
             print("NFCISO15693Tag")
         case .miFare(_):
             print("NFCMiFareTag")
         @unknown default:
             session.invalidate(errorMessage: "Tag not valid.")
             return
         }

     }
     

     
     func sendApduSingle(apduStr:String,comPlete:block){
         let sendData:Data = self.convertHexStrToData(hexStr: apduStr)
         let cmd:NFCISO7816APDU = NFCISO7816APDU.init(data: sendData)!
         var resultError:NSError?
         var result:Data?
         self.currentTag?.sendCommand(apdu: cmd, completionHandler: { [weak self] (resultData, sw1, sw2, error) in
             print("resultData:\(resultData)\nsw1:\(sw1)\nsw2:\(sw2)\nerror:\(String(describing: error))")
             Print ("converting rusultdata to hexadecimal: \ (string (describing: self?. string (from: resultdata)))")

             result = resultData
             resultError = error as NSError?
         })
         
         if resultError == nil{
             comPlete(result ?? Data.init(),true)
         }else{
             comPlete(Data.init(),false)
         }
     }
     
     
     
     //Convert hexadecimal string to data
     func convertHexStrToData(hexStr:String) -> Data {
         let bytes = self.bytes(from: hexStr)
 //        let bytes = hexStr.bytes(from: hexStr)
         return Data.init(_:bytes)
     }
     
     //Convert hexadecimal string to [uint8]
       //Initialize data directly when using
       // Data(bytes: Array<UInt8>)
     func bytes(from hexStr: String) -> [UInt8] {
         Assert (hexstr.count% 2 = = 0, "the input string format is incorrect, 8 bits represent one character")
         var bytes = [UInt8]()
         var sum = 0
         //The utf8 coding range of shaping
         let intRange = 48...57
         //Encoding range of utf8 in lowercase a ~ F
         let lowercaseRange = 97...102
         //Encoding range of utf8 in uppercase A ~ F
         let uppercasedRange = 65...70
         for (index, c) in hexStr.utf8CString.enumerated() {
             var intC = Int(c.byteSwapped)
             if intC == 0 {
                 break
             } else if intRange.contains(intC) {
                 intC -= 48
             } else if lowercaseRange.contains(intC) {
                 intC -= 87
             } else if uppercasedRange.contains(intC) {
                 intC -= 55
             } else {
                 Assertionfailure ("the input string format is incorrect, and each character needs to be within 0 ~ 9, a ~ F, a ~ F")
             }
             sum = sum * 16 + intC
             //Every two hexadecimal letters represent 8 bits, i.e. one byte
             if index % 2 != 0 {
                 bytes.append(UInt8(sum))
                 sum = 0
             }
         }
         return bytes
     }
     //Data to string
     func string(from data: Data) -> String {
             return String(format: "%@", data as CVarArg)
         }

demo

This paper mainly focuses on the interaction between mobile NFC and ISO7816 protocol. For example, the Shanghai transportation card complies with the ISO7816 agreement and can normally obtain the balance and other information of the Shanghai transportation card. (the aid of the card can be obtained from the IPA package of the traffic card)

Recommended Today

JS generate guid method

JS generate guid method https://blog.csdn.net/Alive_tree/article/details/87942348 Globally unique identification(GUID) is an algorithm generatedBinaryCount Reg128 bitsNumber ofidentifier , GUID is mainly used in networks or systems with multiple nodes and computers. Ideally, any computational geometry computer cluster will not generate two identical guids, and the total number of guids is2^128In theory, it is difficult to make two […]