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
199 stars 116 forks source link

Ios 14.2(iPhone XR) Dialog NFC scan don't show #23

Closed saobang187 closed 3 years ago

saobang187 commented 3 years ago

In my widget, I call: print('BEFORE FlutterNfcKit.poll'); var tag = await FlutterNfcKit.poll( // timeout: Duration(seconds: 600), iosMultipleTagMessage: "Multiple tags found!", iosAlertMessage: "Scan your tag");

print(jsonEncode(tag));
print('AFTER FlutterNfcKit.poll');

But dialog NFC scan don't show in iPhone and debug stop at line await FlutterNfcKit.poll(... Please help me check it

kensang commented 3 years ago

I have two testing devices, the "NFC Scanning Window" shows up on one of my devices but not on the other one.

I also tried a native iOS demo app janlionly/NFCReaderWriter, it works on both devices. But for my case, I need to use flutter. I hope this issue can be fixed.

Harry-Chen commented 3 years ago

@kensang Can you provide more detail on this, such as the log before / after the poll call on both two devices? Sorry to bother but we do not have enough devices to test our library on.

kensang commented 3 years ago

@Harry-Chen I just tried to sentry to log my co-worker's result (he is the one using iPhone 11 Pro 14.3), for some reason, this package suddenly works for his phone as well. I am not sure if it's just that there was a mistake with his previous testing or what, but I will let you know what I have done between my previous version and this version just in case:

I have done the following:

I then ask my tester with his iPhone 11 Pro 14.3 to do the following: 1) download from Testflight 2) restart your phone 3) make sure your phone can connect to the internet (so that sentry can log) 4) try to scan an nfc tag

The result from the tester is that it now works, meaning it can detect the nfc tag id & info correctly.

Again, I am not sure if it's a mistake made in previous testing, or is it a re-uploading to testflight, or is it just the "restarting the phone" step. It just works right now. And thank you for your reply.

Harry-Chen commented 3 years ago

@kensang Actually we have encountered some strange behaviour (bug?) with CoreNFC when developing this library, with the similar situation like you described (not responding to poll until a reboot). We haven't figured out how to reproduce (so not reported to Apple yet), but seems frequently calling polling and cancelling the request sometimes triggers this bug.

Again, I am not sure if it's a mistake made in previous testing, or is it a re-uploading to testflight, or is it just the "restarting the phone" step. It just works right now. And thank you for your reply.

So I believe rebooting is the magic. Who knows :-(

devnullpointer commented 3 years ago

Rebooting doesnt work for me. I'm running in debug mode, press start polling and i get the platform exception. I reboot device, relaunch the app in debug mode and still same issue. Reboot is not a solution. There is something wrong with your library.

mbartn commented 3 years ago

I have exactly the same issue on iOS 14.2 (iPhone 7 and iPhone SE 2020), also tried out rebooting

Harry-Chen commented 3 years ago

@devnullpointer Did you get the platform exception directly on the first polling attempt?

dangfan commented 3 years ago

Hi @devnullpointer and @mbartn , do you have any reproducers? It would be much appreciated if you could provide a reproducer.

mbartn commented 3 years ago

Hello @dangfan. First of all, thanks for addressing the issue.

The steps that I went through

  1. Created brand new empty Flutter project.
  2. Added Near Field Communication Tag Reading capability via newest XCode.
  3. Changed iOS deployment target to 13.0.
  4. Added
    <key>NFCReaderUsageDescription</key>
    <string>Some description</string>

    to info.plist

  5. Ran the code presented below on iPhone SE 2020 with iOS 14.2 (18B92)
    
    import 'package:flutter/material.dart';
    import 'package:flutter_nfc_kit/flutter_nfc_kit.dart';

void main() { runApp(MyApp()); }

class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Nfc demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: MyHomePage(), ); } }

class MyHomePage extends StatefulWidget { MyHomePage({Key key}) : super(key: key);

@override _MyHomePageState createState() => _MyHomePageState(); }

class _MyHomePageState extends State { Future _readNfc() async { print("Starting pooling..."); var tag = await FlutterNfcKit.poll(); print("Got it! $tag"); }

@override Widget build(BuildContext context) { return Scaffold( body: Center( child: Text("Hello world!"), ), floatingActionButton: FloatingActionButton( onPressed: _readNfc, child: Icon(Icons.add), ), ); } }


6. Clicked floating button once and got these logs:

Launching lib/main.dart on Michał’s iPhone in debug mode... Automatically signing iOS for device deployment using specified development team in Xcode project: 25UCG8AM44 Running pod install... Running Xcode build... Xcode build done. 46.7s Installing and launching... (lldb) 2021-04-01 20:09:26.178466+0200 Runner[596:44522] Warning: Unable to create restoration in progress marker file Debug service listening on ws://127.0.0.1:60070/wfADq46S2gk=/ws Syncing files to device Michał’s iPhone... fopen failed for data file: errno = 2 (No such file or directory) Errors found! Invalidating cache... fopen failed for data file: errno = 2 (No such file or directory) Errors found! Invalidating cache... flutter: Starting pooling...

and app did nothing, also didn't react on my NFC chip. As you can see app never reached the `print(...)` succeeding `FlutterNfcKit.poll();` call.
6. Clicked button second time and got:

flutter: Starting pooling... [VERBOSE-2:ui_dart_state.cc(186)] Unhandled Exception: PlatformException(406, Cannot invoke poll in a active session, null, null)

0 StandardMethodCodec.decodeEnvelope (package:flutter/src/services/message_codecs.dart:581:7)

1 MethodChannel._invokeMethod (package:flutter/src/services/platform_channel.dart:158:18)

#2 FlutterNfcKit.poll (package:flutter_nfc_kit/flutter_nfc_kit.dart:204:25) #3 _MyHomePageState._readNfc (package:flutter_toy/main.dart:31:15) ``` I also checked logs from XCode but looks like there is also nothing helpful printed.
jiegec commented 3 years ago

Thanks @mbartn for providing the valuable reproducer. After some trial and error, I found that adding these lines to Info.plist works:

    <key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
    <array>
        <string>A00000000386980701</string>
    </array>
    <key>com.apple.developer.nfc.readersession.felica.systemcodes</key>
    <array>
        <string>8008</string>
    </array>

Another way is to enable ISO14443 only without changing Info.plist:

      var tag = await FlutterNfcKit.poll(
          readIso14443A: true,
          readIso14443B: true,
          readIso15693: false,
          readIso18092: false);

So I suspect that iOS checks com.apple.developer.nfc.readersession.felica.systemcodes when FeLiCa is enabled.

What I have tried:

P.S. device restart is required after testing a non-working scenario due to bug of CoreNFC.

In flutter_nfc_kit, the pollingOption passed to iOS by default is [.iso14443, .iso18092, .iso15693] and then CoreNFC might query the Info.plist and found that there are no requested ISO7816 idenfitifers nor FeLiCa system codes and then refuses to show up the scanning window.

I am looking at how to make this error visible to user.

jiegec commented 3 years ago

I have submitted the issue to Apple via Feedback Assistant.

mbartn commented 3 years ago

Appreciate your help @jiegec, adding

readIso14443A: true,
readIso14443B: true,
readIso15693: false,
readIso18092: false,

flags totally solved my issue 👍 You are right, providing some logs in similar cases would be very helpful for future plugin users 🙂

jiegec commented 3 years ago

flags totally solved my issue 👍

Happy to see that!

You are right, providing some logs in similar cases would be very helpful for future plugin users 🙂

It is unfortunate that CoreNFC failed without reporting the error to user.

jiegec commented 3 years ago

Update: Apple says the bug is resolved.

jiegec commented 3 years ago

Update: the bug has been resolved since iOS 14.6.