/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

Primary LanguageDartMIT LicenseMIT

Flutter NFC Kit

pub version Build Example App

Yet another plugin to provide NFC functionality on Android and iOS.

This plugin's functionalities include:

  • read metadata and read & write NDEF records of tags / cards complying with:
    • ISO 14443 Type A & Type B (NFC-A / NFC-B / MIFARE Classic / MIFARE Plus / MIFARE Ultralight / MIFARE DESFire)
    • ISO 18092 (NFC-F / FeliCa)
    • ISO 15963 (NFC-V)
  • transceive commands with tags / cards complying with:
    • ISO 7816 Smart Cards (layer 4, in APDUs)
    • other device-supported technologies (layer 3, in raw commands, Android only)

Note that due to API limitations not all operations are supported on both platforms.

This library uses ndef for NDEF record encoding & decoding.

Setup

Thank nfc_manager plugin for these instructions.

Android

iOS

Usage

Simple example:

import 'package:flutter_nfc_kit/flutter_nfc_kit.dart';
import 'package:ndef/ndef.dart' as ndef;

var availability = await FlutterNfcKit.nfcAvailability;
if (availability != NFCAvailability.available) {
    // oh-no
}

// timeout only works on Android, while the latter two messages are only for iOS
var tag = await FlutterNfcKit.poll(timeout: Duration(seconds: 10),
  iosMultipleTagMessage: "Multiple tags found!", iosAlertMessage: "Scan your tag");

print(jsonEncode(tag));
if (tag.type == NFCTagType.iso7816) {
    var result = await FlutterNfcKit.transceive("00B0950000", Duration(seconds: 5)); // timeout is still Android-only, persist until next change
    print(result);
}
// iOS only: set alert message on-the-fly
// this will persist until finish()
await FlutterNfcKit.setIosAlertMessage("hi there!");

// read NDEF records if available
if (tag.ndefAvailable){
  /// decoded NDEF records (see [ndef.NDEFRecord] for details)
  /// `UriRecord: id=(empty) typeNameFormat=TypeNameFormat.nfcWellKnown type=U uri=https://github.com/nfcim/ndef`
  for (var record in await FlutterNfcKit.readNDEFRecords(cached: false)) {
    print(record.toString());
  }
  /// raw NDEF records (data in hex string)
  /// `{identifier: "", payload: "00010203", type: "0001", typeNameFormat: "nfcWellKnown"}`
  for (var record in await FlutterNfcKit.readNDEFRawRecords(cached: false)) {
    print(jsonEncode(record).toString());
  }
}

// write NDEF records if applicable
if (tag.ndefWritable) {
  // decoded NDEF records
  await FlutterNfcKit.writeNDEFRecords([new ndef.UriRecord.fromUriString("https://github.com/nfcim/flutter_nfc_kit")]);
  // raw NDEF records
  await FlutterNfcKit.writeNDEFRawRecords([new NDEFRawRecord("00", "0001", "0002", "0003", ndef.TypeNameFormat.unknown)]);
}

// Call finish() only once
await FlutterNfcKit.finish();
// iOS only: show alert/error message on finish
await FlutterNfcKit.finish(iosAlertMessage: "Success");
// or
await FlutterNfcKit.finish(iosErrorMessage: "Failed");

A more complicated example can be seen in example dir.

Refer to the documentation for more information.

Error codes

We use error codes with similar meaning as HTTP status code. Brief explanation and error cause in string (if available) will also be returned when an error occurs.