How do you read and write NFC from your own code?
Through the API of the platform the code runs on: the NFC framework on Android, Core NFC on iPhone, Web NFC in Chrome for Android, and PC/SC for a reader plugged into a computer. Each one decides what a program may send to a tag, when it may listen for one, and what it must declare first.
Four ways in, four sets of rules
On Android, the NFC framework hands a discovered tag to an activity, which can read and write NDEF, send raw commands to the tag, or answer a reader through host card emulation.
On iPhone, Core NFC lets an app read inside a session that the system displays and ends, the model this site describes on the scan sheet page.
In a browser, Web NFC reads and writes NDEF from a web page. Chrome documents it as available on Android from Chrome 89, and limits it to NDEF on purpose: no raw commands, no card emulation.
On a computer, a USB reader is reached through PC/SC, the specification computers use to talk to smart card readers, and the program talks to the tag through the reader rather than through a phone.
They differ in what they can send to a tag, and they differ even more in when they are allowed to listen. That second difference is the one a port from one platform to another gets wrong.
What code has to declare
None of them reaches the radio unannounced. An Android app asks for android.permission.NFC, which the permission reference classes as normal, so it is granted at install without a prompt.
From Android 17, an app that targets a newer SDK must also protect each activity that receives tags with android.permission.DISPATCH_NFC_MESSAGE, according to the NFC basics guide, so that only the NFC service can start it.
An iPhone app declares the Tag Reading capability and a usage description before Core NFC opens a session, and a tag session that reads ISO 7816 tags also lists the application identifiers it will select. The declarations page covers all three.
A web page needs a secure origin, a top level frame and a gesture from the visitor, such as a tap on a button, before Chrome asks for the nfc permission.
What the field does to code
A tag is present for as long as a hand holds it still, and the code runs inside that window. The TagTechnology reference marks every exchange as blocking and forbids it on the main thread, and a tag that leaves mid exchange raises TagLostException.
Tests at a desk hide this. The phone lies flat, the tag does not move, and the window never closes. The same code in a visitor's hand meets a window that closes halfway, and code that has never met that case treats it as a crash.
The tag is also not what it was a second ago. Android caches what it read at discovery and never updates those values, so a program that writes and then trusts the cached copy reads back its own assumption.
Checking what the code wrote
Read the result back with a tool that is not the code under test. A bug that writes the wrong record type can read it back as the right one, because the same bug decodes it.
NFC Tools, published by the same company as this site, shows the records a tag holds and the technologies it reports, which settles most disagreements between a program and its author.
Then read the tag on the other platform. A message an Android parser accepts can still do nothing on an iPhone, a platform decision covered on the iOS records page.
All guides in this section
- Android
- iOS and Core NFC
- Web NFC and cross platform
- Below NDEF
- Card emulation in code
- Readers and devices
- Testing and debugging
Android
- Reader mode or foreground dispatch: which one should an Android app use?
- How do you declare the tags an Android app should receive?
- Which technology class should Android code open for a given tag?
- How do you write an NDEF message from an Android app?
- Can an Android app react to a tag without showing a screen?
- How do you handle a tag that arrives while your activity is open?
- Which controller limits must Android code check at runtime?
iOS and Core NFC
- NDEF session or tag session: which one should an iOS app open?
- What does an iOS app have to declare before it can read a tag?
- How do you write and lock an NDEF tag from an iOS app?
- How does an iOS app receive a tag read in the background?
- How do you read several tags in one iOS session?
- Can an iOS app read a tag's identifier?
Web NFC and cross platform
Below NDEF
- How do you send a raw command to a tag?
- What is an APDU, and when does your code need one?
- How do you read the memory of a Type 2 tag page by page?
- How do you read the blocks of an ISO/IEC 15693 tag?
- How does code find the NDEF file on a Type 4 tag?
- How does code authenticate to a password protected tag?
- How do you detect that a tag has left the field?
- How do you write a tag so an interrupted write cannot pass for valid?
- How do you write a tag's configuration pages without ruining it?
- How does a server read the identifier a tag mirrors into its URL?
Card emulation in code
Readers and devices
- How does a computer talk to a USB NFC reader?
- Which reader chip suits a microcontroller project?
- Why does a hobby reader module miss some tags?
- What is a dynamic tag, and when does a device need one?
- Can a phone configure a device that is switched off?
- How do you design an NFC antenna for your own board?
- Can your own device act as a tag for a phone?
Testing and debugging
- Why does a read fail with a tag lost error?
- Why does a Core NFC session end on its own?
- Why does a command time out, and how long should code wait?
- Can NFC code be tested without a tag in hand?
- Which tags should a developer keep for testing?
- How do you see what an app and a tag actually exchange?
- What should an app do when NFC is off or missing?
- Why does code written for one chip break on another of the same type?
- Should an NFC app install on phones without NFC?
Frequently asked questions
Which platform should a first NFC project target?
Android, if the project needs to talk to the tag itself. Its framework reaches NDEF, raw commands and card emulation, and a tag can start an app that is not open. iOS adds a session the system controls and Web NFC stops at NDEF, so both are easier to add once the exchange works.
Does reading tags need a permission prompt?
Not on Android, where the NFC permission is a normal one granted at install. Web NFC asks the visitor, and only in response to a gesture such as a tap on a button.
Can NFC code be tested without a phone?
Parsing and building NDEF messages can. Everything that depends on the field, such as timing, a tag leaving mid write or a controller that refuses a command, only appears with real tags on real phones.
Where do commands specific to one chip come from?
From that chip's datasheet. This section covers the commands the NFC Forum tag types define, and leaves the memory map of individual chips to the datasheets on wakdev.com.