Ios 14.2(iPhone XR) Dialog NFC scan don't show
saobang187 opened this issue · 15 comments
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
I have two testing devices, the "NFC Scanning Window" shows up on one of my devices but not on the other one.
- this library works on iPhone XS Max (iOS 14.3)
- this library doesn't work ("NFC Scanning Window" not showing up) on iPhone 11 Pro (iOS 14.3)
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.
@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.
@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:
- change the build version number of my iOS app
- install flutter_sentry 0.4.4
- setup and implement flutter_sentry the way the flutter_sentry example does it
- upload from testflight
I then ask my tester with his iPhone 11 Pro 14.3 to do the following:
- download from Testflight
- restart your phone
- make sure your phone can connect to the internet (so that sentry can log)
- 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.
@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 :-(
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.
I have exactly the same issue on iOS 14.2 (iPhone 7 and iPhone SE 2020), also tried out rebooting
@devnullpointer Did you get the platform exception directly on the first polling attempt?
Hi @devnullpointer and @mbartn , do you have any reproducers? It would be much appreciated if you could provide a reproducer.
Hello @dangfan. First of all, thanks for addressing the issue.
The steps that I went through
- Created brand new empty Flutter project.
- Added Near Field Communication Tag Reading capability via newest XCode.
- Changed iOS deployment target to
13.0
. - 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<MyHomePage> {
Future<void> _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),
),
);
}
}
- 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)
<asynchronous suspension>
#2 FlutterNfcKit.poll (package:flutter_nfc_kit/flutter_nfc_kit.dart:204:25)
<asynchronous suspension>
#3 _MyHomePageState._readNfc (package:flutter_toy/main.dart:31:15)
<asynchronous suspension>
I also checked logs from XCode but looks like there is also nothing helpful printed.
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:
- All Enabled + Info.plist(FeLiCa+ISO7816): works
- Only ISO14443 Enabled + Info.plist(None): works
- All Enabled + Info.plist(None): not working
- ISO14443 + ISO18092 Enabled + Info.plist(FeLiCa): works
- ISO14443 + ISO18092 Enabled + Info.plist(ISO7816): not working
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.
I have submitted the issue to Apple via Feedback Assistant.
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 🙂
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.
Update: Apple says the bug is resolved.
Update: the bug has been resolved since iOS 14.6.