Skip to content
Language: EN

What does an iOS app have to declare before it can read a tag?

Three things, all in the project: the Near Field Communication Tag Reading capability, which adds the entitlement; an NFCReaderUsageDescription string in Info.plist, without which Apple says the app exits when it tries to read; and, for a tag session, the ISO 7816 application identifiers or FeliCa system codes the app will select.

The capability and its entitlement

An app reads tags only with the Near Field Communication Tag Reading capability turned on for its target. Apple's tag reader sample lists what that step does: it adds the tag reading feature to the App ID and the reader session formats entitlement to the entitlements file.

The entitlement's reference page now lists a single value, TAG, described as read and write access through NFCTagReaderSession, and its instruction is to enable the capability in Xcode rather than to edit the file.

The usage description

NFCReaderUsageDescription, shown in Xcode as Privacy - NFC Scan Usage Description, is a string in Info.plist that tells people why the app wants the NFC hardware. Its reference page marks it as required for any app using APIs that access that hardware.

Its absence is not a warning. The sample states that an app which attempts to read a tag without the key and its string exits.

It is also a different text from the one the scan sheet shows. The alertMessage documentation separates the two: the usage description explains why the app asks, and the alert message tells the user what to do during a scan.

Application identifiers and system codes

A tag session delivers an ISO 7816 tag only for the application identifiers listed under com.apple.developer.nfc.readersession.iso7816.select-identifiers in Info.plist. The NFCISO7816Tag documentation describes what happens: the session sends a SELECT for each identifier, in the order of the list, and reports the tag after the first one that succeeds, with the selected identifier in initialSelectedAID.

The order therefore matters, and so does one identifier in particular. Listing D2760000850101, the NDEF application on MIFARE DESFire tags, makes such a tag arrive as NFCISO7816Tag; leaving it out delivers the same tag as NFCMiFareTag.

FeliCa tags need their system codes listed the same way, in the key Apple's reference names ISO18092 system codes for NFC Tag Reader Session. From iOS 26.4, a session Configuration can narrow the identifiers per session, but only among those already in Info.plist: the reference says unknown entries are dropped.

What the code still checks

Declarations do not guarantee hardware. readingAvailable says whether the device can read tags, and Apple's framework overview asks apps to check it before starting a session.

And some identifiers cannot be selected at all. The tag session documentation says it does not support selecting payment related application identifiers, and points apps in the European Union to NFCPaymentTagReaderSession.

Frequently asked questions

Does an app that only reads NDEF need the entitlement?

Yes. Apple's tag reader sample, which only reads NDEF, turns on the Tag Reading capability, and that capability is what adds the entitlement.

What happens if NFCReaderUsageDescription is missing?

Apple's sample states that the app exits when it attempts to read a tag without the key and its string.

Why does my DESFire tag arrive as ISO 7816 instead of MIFARE?

Info.plist lists D2760000850101, the NDEF application identifier on DESFire tags. Remove it to receive the tag as NFCMiFareTag.

Can an app select a payment card's application?

Not through NFCTagReaderSession, which does not support payment related identifiers. In the European Union, Apple documents NFCPaymentTagReaderSession for that case.