What does an iOS app need to emulate a card?
Three things Apple controls: the card session entitlement, granted on application under a commercial agreement; a device and an environment the system finds eligible; and code that answers APDUs from the session event stream. Core NFC offers CardSession from iOS 17.4, behind a system sheet.
The entitlements come first
CardSession, from iOS 17.4, is the class that emulates a card, and Apple's documentation lists what it covers in the European Economic Area: in store payments, car keys, closed loop transit, corporate badges, hotel keys, loyalty and event tickets.
Three entitlements govern it. com.apple.developer.nfc.hce allows the API at all, and without it creating a session raises a fatal error. The select identifier prefixes entitlement lists what the app answers for: full application identifiers, registered provider identifiers, or prefixes at least as long as the provider identifier. The default contactless app entitlement lets a person choose the app in Settings as the default for contactless.
Each of the three pages points to the same place, an application form for host card emulation based contactless transactions for banking and wallet apps in the European Economic Area. The commercial side of that is covered by the iPhone emulation page; the technical consequence is that the code below runs only where Apple has said yes.
Two checks before anything appears
Apple asks for three values before a session is created: NFCReaderSession.readingAvailable, CardSession.isSupported for the device, and CardSession.isEligible for the current environment, which is asynchronous. The reference is explicit about why each matters: creating a session on an unsupported device raises a fatal error, and an ineligible one would show a system card session interface for nothing.
So the check belongs before the button, not after it. An app that offers to present a card and then fails the eligibility test has already promised something the system will not deliver.
The session, event by event
A card session is a stream rather than a delegate. The app creates it, iterates eventStream, and receives sessionStarted once the app holds the NFC resource, then readerDetected when the device senses a reader's field.
Emulation starts when the app calls startEmulation(), which presents the system modal interface, with alertMessage set beforehand. From there each event carries an APDU payload to process and answer with respond(response:), and Apple warns that a reader may treat a late answer as a timeout. readerDeselected arrives when the reader goes, stopEmulation(status:) shuts the radio interface with a final status shown to the user, and invalidate() releases the session.
startEmulation() throws where the platform refuses: the system is not available, access was not accepted, eligibility failed, or the radio is disabled. Those four cases are worth distinct messages, since only one of them is a problem the user can fix.
Which app a tap reaches
The default contactless app answers a tap unless another app asks for the field. NFCPresentmentIntentAssertion is that request: acquired from the foreground, it prevents the system default app from launching in response to a gesture or a reader's field, and Apple ties it to a person actively choosing a credential in your app.
It does not last. The assertion expires when the object deinitializes, when the app goes to the background, or after fifteen seconds, and a new one can only be acquired after a fifteen second cool down. It is also not required before presenting the sheet.
Android arranges the same question differently, with a wallet role and a foreground preference that any app may use; the routing page covers it. The platforms agree on one point: the user, not the reader, decides which app speaks.
Frequently asked questions
Can any iOS app emulate a card?
No. The card session entitlement is granted on application under an agreement with Apple, and creating a session without it raises a fatal error.
Which transactions does Apple list?
In store payments, car keys, closed loop transit, corporate badges, hotel keys, loyalty and event tickets, in the European Economic Area.
Does the user see something during emulation?
Yes. Starting emulation presents a system modal interface, and the text in it is the alert message the app sets beforehand.
How long does a presentment intent assertion last?
Fifteen seconds, or until the app leaves the foreground or the object deinitializes, and a new one waits through a fifteen second cool down.