nfcim / flutter_nfc_kit

Flutter plugin to provide NFC functionality on Android and iOS, including reading metadata, read & write NDEF records, and transceive layer 3 & 4 data with NFC tags / cards
https://pub.dev/packages/flutter_nfc_kit
MIT License
200 stars 121 forks source link

Long discovery times for NTAG 424 #180

Open josefshamstr opened 2 months ago

josefshamstr commented 2 months ago

Hey there, I'm struggling with improving the discovery times for an NTAG 424. (The tag shouldn't be the culprit most likely as the tag is significantly found faster on NFC Tools App)

This is the code that outputs the logs seen further down below, I also included a comparison with an Ntag 213

`Future<NfcPayloadStruct?> nfcKit(BuildContext context) async { final startTime = DateTime.now(); print('nfcKit function started: $startTime');

try { print('Checking NFC availability: ${DateTime.now()}'); var availability = await FlutterNfcKit.nfcAvailability; print('NFC availability checked: ${DateTime.now()}, Result: $availability');

if (availability != NFCAvailability.available) {
  return null;
}

print('Starting NFC session: ${DateTime.now()}');
var tag = await FlutterNfcKit.poll(
  timeout: Duration(seconds: 5),
  iosMultipleTagMessage: "Multiple tags found!",
  iosAlertMessage: "Scan your tag",
  readIso14443A: true,
);
final tagDetectionTime = DateTime.now();
print('Tag detected: $tagDetectionTime, Tag type: ${tag.type}, Tag ID: ${tag.id}');

if (tag.ndefAvailable == true) {
  print('NDEF available, starting to read: ${DateTime.now()}');
  var ndefRecords = await FlutterNfcKit.readNDEFRecords(cached: false);
  final ndefReadTime = DateTime.now();
  print('NDEF data read: $ndefReadTime, Number of records: ${ndefRecords.length}');

  // Process NDEF data...

  await FlutterNfcKit.finish(iosAlertMessage: "■■■■");
  final endTime = DateTime.now();
  print('NFC session ended: $endTime');

  // Calculate and print time differences
  int startToDetection = tagDetectionTime.difference(startTime).inMilliseconds;
  int detectionToRead = ndefReadTime.difference(tagDetectionTime).inMilliseconds;
  int totalTime = endTime.difference(startTime).inMilliseconds;

  print('NTAG ${tag.type == NFCTagType.iso7816 ? "424" : "213"}:');
  print('1. Start to Tag Detection: ~$startToDetection ms (${(startToDetection / 1000).toStringAsFixed(2)} seconds)');
  print('2. Tag Detection to NDEF Reading: ~$detectionToRead ms');
  print('3. Total Time (Start to End): ~$totalTime ms (${(totalTime / 1000).toStringAsFixed(2)} seconds)');

  return NfcPayloadStruct(
    uri: ndefRecords.first.uri.toString(),
    tagUID: tag.id.toString(),
  );
}

// End the NFC session if no NDEF data was found
await FlutterNfcKit.finish(iosAlertMessage: "■■■■");

} catch (e) { print('Error occurred: ${DateTime.now()}, Error: $e'); await FlutterNfcKit.finish(iosErrorMessage: "Error reading the tag."); }

print('nfcKit function ended without result: ${DateTime.now()}'); return null; } `

The outputs for the print statements:

NTAG 424:

  1. Start to Tag Detection: ~1393 ms (1.39 seconds)
  2. Tag Detection to NDEF Reading: ~67 ms
  3. Total Time (Start to End): ~1463 ms (1.46 seconds)

NTAG 213:

  1. Start to Tag Detection: ~193 ms (0.19 seconds)
  2. Tag Detection to NDEF Reading: ~89 ms
  3. Total Time (Start to End): ~286 ms (0.29 seconds)

About the setup, I placed my iPhone on both tags to have the same conditions that the tags are available to be found from the very first moment.

Also I noticed that the problem is more prominent on iOS - don't have an Android unfortunately atm to provide timestamps as well

If you have any ideas how this could be well improved, let me know ☺️

Harry-Chen commented 3 weeks ago

Sorry but I do not currently have NTAG424 available. 1.4s polling time does not look normal. Have you tried using another tag (i.e. confirming that it is not the problem w.r.t. one specific tag)?