nfc_in_flutter
NFC in Flutter is a plugin for reading and writing NFC tags in Flutter. It works on both Android and iOS with a simple stream interface.
Usage
Read NFC tags
Read one NFC tag
Writing to tags
You can access a message's NFC tag using the NDEFMessage
's .tag
property. The tag has a .write
method, which allows you to write a NDEF message to the tag.
Note that the read stream must still be open when the .write
method is called. This means that the once
argument in .readNDEF()
cannot be used.
You can also use the NFC.writeNDEF(NDEFMessage)
method, which wraps the code above with support for the once
argument.
If you only want to write to one tag, you can set the once
argument to true.
And if you would rather use a Future
based API, you can await the returned stream's .first
method.
Example
Full example in example directory
Installation
Add nfc_in_flutter
to your pubspec.yaml
iOS
On iOS you must add turn on the Near Field Communication capability, add a NFC usage description and a NFC entitlement.
Turn on Near Field Communication Tag Reading
Open your iOS project in Xcode, find your project's target and navigate to Capabilities. Scroll down to 'Near Field Communication Tag Reading' and turn it on.
Turning on 'Near Field Communication Tag reading'
- Adds the NFC tag-reading feature to the App ID.
- Adds the Near Field Communication Tag Reader Session Formats Entitlement to the entitlements file.
from developer.apple.com: Building an NFC Tag-Reader app
NFC Usage Description
Open your ios/Runner/Info.plist
file and add a new NFCReaderUsageDescription
key. It's value should be a description of what you plan on using NFC for.
Android
Add the following to your app's AndroidManifest.xml
file:
If your app requires NFC, you can add the following to only allow it to be downloaded on devices that supports NFC:
"What is NDEF?"
If you're new to NFC you may come to expect a lot of readNFC()
calls, but instead you see readNDEF()
and NDEFMessage
. NDEF is just a formatting standard the tags can be encoded in. There are other encodings than NDEF, but NDEF is the most common one. Currently NFC in Flutter only supports NDEF formatted tags.
Host Card Emulation
NFC in Flutter supports reading from emulated host cards*.
To read from emulated host cards, you need to do a few things.
- Call
readNDEF()
with thereaderMode
argument set to an instance ofNFCDispatchReaderMode
. - Insert the following
<intent-filter />
in yourAndroidManifest.xml
activity:
- Not properly tested on iOS
⚠️ Multiple reader modes
If you start a readNDEF()
stream with the reader mode set to an instance of NFCDispatchReaderMode
, while another stream is active with the NFCNormalReaderMode
, it will throw a NFCMultipleReaderModesException
.
Platform differences
When you call readNDEF()
on iOS, Core NFC (the iOS framework that allows NFC reading) opens a little window. On Android it just starts listening for NFC tag reads in the background.
image from developer.apple.com: Near Field Communication
⚠️ This will also freeze Flutter while open. Please send a Pull Request if you can fix this.
Error handling
Errors are no exception to NFC in Flutter (hah, get it). The stream returned by NFC.readNDEF()
can send 7 different exceptions, and even worse: they are different for each platform!
See the full example in the example directory for an example on how to check for errors.
Exceptions for both platforms
NDEFReadingUnsupportedException
Thrown when a reading session is started, but not actually supported.
iOS
NFCUserCanceledSessionException
Thrown when the user clicks Cancel/Done core NFC popup. If you don't need to know if the user canceled the session you can start reading with the throwOnUserCancel
argument set to false
like so: readNDEF(throwOnUserCancel: false)
NFCSessionTimeoutException
Core NFC limits NFC reading sessions to 60 seconds. NFCSessionTimeoutException
is thrown when the session has been active for 60 seconds.
NFCSessionTerminatedUnexpectedlyException
Thrown when the reading session terminates unexpectedly.
NFCSystemIsBusyException
Throw when the reading session fails because the system is too busy.
Android
NFCIOException
Thrown when a I/O exception occurs. Will for example happen if a tag is lost while being read or a tag could not be connected to.
NDEFBadFormatException
Thrown when the tag is expected to NDEF formatted, but it is incorrectly formatted.