Search code examples
iosreact-nativenfcreact-native-nfc-manager

ISO14443 - React Native NFC sometimes "Tag connection lost" - only on iOS


Context & Problem:

  • I’m writing a React Native application which has to communicate with NFC MiFare Ultralight tags. I have NXP NTAG I2C PLUS ISO14443-3 tags.

  • I’m using the react-native-nfc-manager library for this. On android I didn’t notice any problems just on the iOS side. I’m testing on iOS 13 and 14 and my device is an iPhone 7.

  • I am able to find and connect to NFC Mifare Ultralight tags (can read and write them too), but in the 75% of the situations I get the following error during the communications:

[CoreNFC] 00000002 803f43f0 -[NFCTagReaderSession transceive:tagUpdate:error:]:771  Error Domain=NFCError Code=100 "Tag connection lost" UserInfo={NSLocalizedDescription=Tag connection lost}

This problem only appears on iOS. Android works fine.


How I communicate:

  • I added the NDEF and TAG formats to the entitlements file to the …readersession.formats.
  • I also added value to the info.plist for the Privacy - NFC Scan Usage Description.
  • I’m requesting NfcTech.MifareIOS tech and calling the NfcManager.sendMifareCommandIOS() method as the library’s MiFare example shows. I’ve tried to use other transmitter methods and requesting other tech types, but in those situations I didn’t even get any responses.

This is how I create the writing commands and how I call my transmit method:

// WRITE COMMAND looks like: [0xA2, Addr, datas]
const writeCommand = [0xa2, offset, data[0], data[1], data[2], data[3]];
const response = await this.transmit(writeCommand);

This is how I create the reading commands:

// FAST_READ COMMAND looks like: [0x3A, StartAddr, EndAddr]
const readCommand = [0x3a, offset, offset + readLength];

And here is my transmit method:

private async transmit(msg: number[]): Promise<number[]> {
  ...
  const cmd = Platform.OS === 'ios' ? NfcManager.sendMifareCommandIOS : NfcManager.transceive;
  return await cmd(msg);
}

What I noticed and tried:

  • I noticed that the iPhone is very sensitive for the positioning. If I hold the device in a certain position I can also achieve 80% success. I noticed too that if I leave the phone on the tag I get this error more often. I got better results when I took away the phone after a communication and then put it back again.
  • When I added some sleep after the communication for example 100 ms, the communication seemed to be more stable. Because of the number of communications, I can't wait that much. Even if I wait I get the error, but fewer times.
  • I saw a very similar issue which describes a CRC problem, which appears when you try to send CRC, but that has been automatically added already by the iOS. I’m not sending the CRC (which was the solution in the mentioned issue), so that shouldn't be a problem.
  • Also saw the following issue with similar problem, but I have another type of tags - ISO-14443 and I'm also able to connect and communicate with the tags which wasn't the case in the mentioned issue.
  • Tried to invalidate the session after each communication, but didn’t help to stabilize the connection.
  • Tried with multiple tags (but with the same tag type), but got the same results.

I'd appreciate very much any ideas that could help me solve this problem.


Solution

  • At the end I managed to try out our app on multiple iPhones and the NFC worked properly. We also found out that our test device is a refurbished unit and we think that maybe that is the problem's cause.