I've also been working with the NFCTagReaderSession, NFCISO7816Tag, and NFCISO7816APDU Core-NFC elements to communicate with NFC-Devices via the ISO14443/ISO7816 protocals.
Right now I'm trying to reduce the Communication Failure Rate which I have found is directly proportional to three factors;
1) The Size of the APDU Command sent by IOS, and the Size of the APDU Response of the NFC-Device.
Where the larger they are, the more likely communication is to fail.
2) The number of APDU Command/Response pairs you are sending/processing in a row via a single Session.
The more APDU commands you try to send during a Session, the more likely communication is to fail.
3) The positioning of the IOS-Device relative to the NFC-Device when initiating the Scan.
The closer you are to the RF-Field of the NFC-Device when you begin a Scan, the more likely communication is to fail.
The less Direct the Angle of approach of the IOS-Device to the RF-Field of the NFC-Device, the more likely communication is to fail.
Point 3 is the largest contributing factor, where communication can fail 90% of the time.
Point 2 is the next largest contributor, where communication starts failing 40-50% of the time just from trying to Send/Process Two
APDU Command/Response pairs during a Session.
For reference, this Forum Post also discusses Communication Failure that has been observed
~ see https://forums.developer.apple.com/message/393076#393076
When communication explicitly fails, I get one of two Errors and Debbugger-Console-Messages
within the completionHandler of the NFCISO7816Tag.sendCommand method;
1)
Debugger-Log:
2019-11-18 15:20:35.143756-0500 NFC-RW-Basic[1413:723511] [CoreNFC] 00000002 80c02600
-[NFCTagReaderSession _connectTag:error:]:573
Error Domain=NFCError Code=100 "Stack Error"
UserInfo={
NSLocalizedDescription=Stack Error,
NSUnderlyingError=0x282c90990 {
Error Domain=nfcd Code=29 "Tag Error"
UserInfo={NSLocalizedDescription=Tag Error}
}
}
Error:
Domain=NFCError Code=104 "Tag is not connected" UserInfo={NSLocalizedDescription=Tag is not connected}
2)
Debugger-Log:
2019-11-18 15:40:25.913306-0500 NFC-RW-Basic[1418:727395] [CoreNFC] 00000002 82031300
-[NFCTagReaderSession transceive:tagUpdate:error:]:735
Error Domain=NFCError Code=100 "Tag connection lost"
UserInfo={
NSLocalizedDescription=Tag connection lost
}
Error:
Domain=NFCError Code=100 "Tag connection lost" UserInfo={NSLocalizedDescription=Tag connection lost}
TheNFCError Code=104 "Tag is not connected"error being the more common of the two that occurs.
But I've also seen behavior where upon initiating the Scan, the IOS-Device does not detect the NFC-Device at all
and eventually times out (after 60 seconds by default) if you do not Cancel.
I've found that using the NFCTagReaderSession.restartPolling() method within the
completionHandler of NFCISO7816Tag.sendCommand can help mask the communication failures from the user,
where eventually communication may succeed at some point during the Session.
nfciso7816Tag.sendCommand(apdu: readAPDU) { (responseA: Data, sw1A: UInt8, sw2A: UInt8, errorA: Error?) in
guard error == nil && (sw1 == 0x90 && sw2 == 0x00) else {
let retryInterval = DispatchTimeInterval.milliseconds(100)
DispatchQueue.global().asyncAfter(deadline: .now() + retryInterval, execute: {
session.restartPolling()
})
return
}
This does not help however for the case when the IOS-Device has started a Scan that fails to detect the NFC-Device.
There is also an NFCTagCommandConfiguration class
that seems like it could potentially help in configuring the NFCTagReaderSession to better reduce/handle Communication failure,
but I've yet to see any documentation on how to actually use it
~ see https://forums.developer.apple.com/thread/125199