Skip to main content
For DESFire, JavaCard applets, transit cards, EMV-adjacent work — anything where you select an application by AID and exchange APDUs.
The builders return a command; sendApdu sends one. The full API, including chaining and the 61xx/6Cxx follow-ups it handles for you, is in Tag protocols.

The iOS rule that catches everyone

iOS does not deliver an ISO 7816 tag to your app unless the AID you are selecting is declared in Info.plist. Not an error, not an empty result — the tag simply never arrives, exactly as if it were not there.This is the single most common reason a card that works on Android appears unreadable on iOS.
Android has no such restriction, so the same code works there with no declaration at all. That asymmetry is why this is easy to ship and hard to diagnose.

Expo

app.json
Write the AID as plain uppercase hex: no 0x, no spaces, no separators. The plugin rejects anything else, and anything outside the 5-to-16-byte range ISO 7816-4 allows, because Apple rejects those when the profile is built — a long way from where the mistake was made.

A trap worth knowing about

Declaring D2760000850101, the NDEF application AID, changes how iOS presents cards that support it: a DESFire card then arrives as an ISO 7816 tag rather than a MIFARE one, so tag.is('mifareUltralight') and the MIFARE-specific commands stop matching.That is a legitimate thing to want and a baffling thing to trip over, so the plugin warns when it sees it.

Bare React Native

ios/<App>/<App>.entitlements

ios/<App>/Info.plist

Add one <string> per AID your app selects. A card whose AID is not listed is never handed over.

android/app/src/main/AndroidManifest.xml

Nothing ISO 7816-specific: Android decides nothing at the radio.

Timeouts

Crypto takes longer than the platform’s default patience. DESFire authentication and GlobalPlatform key derivation both routinely exceed Android’s 125 ms presence check, and the OS then declares the tag lost part-way through an exchange that was going fine:
On iOS the equivalent limits are the session’s 60 seconds and roughly 20 seconds of connected tag. Neither can be extended, so a long personalisation sequence has to be split across sessions.

Next

Tag protocols

Command builders, chaining, and status words.

Card emulation

The other side: answering a terminal’s SELECT.