NDEF session or tag session: which one should an iOS app open?
An NDEF session, when the app only reads or writes messages: it covers NFC Forum types 1 to 5 and needs the fewest declarations. A tag session, from iOS 13, when the app must talk to the chip itself through ISO 7816 APDUs, ISO 15693 blocks, FeliCa or MIFARE commands. Only one session of any type runs at a time.
What an NDEF session does
Core NFC reads NDEF data from tags of types 1 through 5, according to Apple's framework overview, and NFCNDEFReaderSession is the session built for it. It delivers each message to its delegate through readerSession(_:didDetectNDEFs:), with no tag object and no command.
From iOS 13, the same session can also hand over the tags themselves. A delegate that implements readerSession(_:didDetect:) receives NFCNDEFTag objects, connects to one, and can query, write and lock it, as the writing page describes.
The invalidateAfterFirstRead flag decides how long the session lives. Set to true, it ends after the first tag read successfully; set to false, it keeps reading until it times out or is cancelled. Apple's note on the initializer says to set it to false for a session that writes.
What a tag session adds
NFCTagReaderSession, available from iOS 13, detects tags by radio technology rather than by content. Its polling options choose what it looks for: iso14443 for ISO 7816 compatible and MIFARE tags, iso15693 for vicinity tags, iso18092 for FeliCa, and from iOS 16 a pace option.
Each detected tag arrives as an NFCTag value whose case gives the protocol: NFCISO7816Tag for APDUs, NFCISO15693Tag for block commands, NFCFeliCaTag, or NFCMiFareTag for MIFARE commands. Each of these also conforms to NFCNDEFTag, so a tag session reads and writes NDEF too.
The price is in declarations. On top of the entitlement and the usage description every Core NFC app needs, the class documentation delivers an ISO 7816 tag only for application identifiers listed in Info.plist, as the declarations page explains.
One session at a time
Only one reader session of any type can be active in the system at a time, the base class documentation says, and additional sessions wait in a queue served in order. An app that starts a second session while the first is open waits for the first to end.
A session also needs hardware. readingAvailable answers before anything is created, and Apple asks apps to check it first; Core NFC is not available in app extensions at all.
And a session ends for good. Once invalidated it cannot scan again, and the app creates a new one, which is what Apple's tag reader sample does after every invalidation.
Choosing between them
| Question | NDEF session | Tag session |
|---|---|---|
| Available from | iOS 11 for reading, iOS 13 for writing | iOS 13 |
| What it delivers | Messages, or NDEF tags through didDetect | Tags by protocol, each one NDEF capable |
| Commands to the chip | None | APDUs, ISO 15693 blocks, FeliCa and MIFARE commands |
| Extra declarations | None | Application identifiers for ISO 7816, system codes for FeliCa |
Choose the NDEF session when the tag carries a message and the app's job is that message. Choose the tag session when the app needs the chip: an identifier, a counter, a password, a block of memory outside NDEF.
Frequently asked questions
Can an iOS app read a tag without the scan sheet?
No. A reader session shows the system scanning alert while it runs, and the app only chooses the message in it, through alertMessage.
Does a tag session read NDEF as well?
Yes. Every tag type it delivers also conforms to NFCNDEFTag, so the app can read and write NDEF after connecting.
Can two sessions run at the same time?
No. Only one reader session of any type is active in the system, and the others wait in a queue served in order.
Why does my NDEF session end after the first tag?
invalidateAfterFirstRead is true, and the delegate receives readerSessionInvalidationErrorFirstNDEFTagRead when the session ends. Set it to false to keep reading or to write.