iOS Core NFC Programming Guide
Reading and Writing NFC Tags in Swift
iOS NFC development guide using Core NFC framework to read and write tags in Swift. Covers NFCNDEFReaderSession, background tag reading, write support, and App Clip integration.
iOS Core NFC Programming Guide
Apple introduced Core NFC in iOS 11 and has progressively expanded its capabilities with each major release. As of iOS 15, iPhones can read and write most NFC Forum tag types, though some restrictions remain compared to Android.
Core NFC Framework Overview
Core NFC is in the CoreNFC framework (import CoreNFC). The two primary session classes are:
| Class | Purpose | iOS Version |
|---|---|---|
NFCNDEFReaderSession |
Read ndef-messages from any tag | 11+ |
NFCTagReaderSession |
Low-level access to specific tag tech (ISO 14443, 15693, FeliCa) | 13+ |
NFCNDEFTag protocol |
Read and write NDEF on discovered tags | 13+ |
Entitlement required: Add com.apple.developer.nfc.readersession.formats to your .entitlements file and configure the Privacy NFC Scan Usage Description in Info.plist.
<!-- Info.plist -->
<key>NFCReaderUsageDescription</key>
<string>Read NFC tags to verify product authenticity.</string>
NDEF Reading with NFCNDEFReaderSession
import CoreNFC
class NFCReader: NSObject, NFCNDEFReaderSessionDelegate {
var session: NFCNDEFReaderSession?
func beginScan() {
session = NFCNDEFReaderSession(delegate: self, queue: nil, invalidateAfterFirstRead: false)
session?.alertMessage = "Hold your iPhone near an NFC tag."
session?.begin()
}
func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) {
for message in messages {
for record in message.records {
print("TNF: \(record.typeNameFormat.rawValue)")
print("Payload: \(record.payload)")
}
}
}
func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) {
print("Session invalidated: \(error.localizedDescription)")
}
}
Tag Sessions and Writing
Writing requires NFCTagReaderSession (iOS 13+). The flow: detect tag → connect → cast to NFCNDEFTag → write message.
func readerSession(_ session: NFCTagReaderSession, didDetect tags: [NFCTag]) {
guard let tag = tags.first else { return }
session.connect(to: tag) { error in
guard error == nil else { session.invalidate(errorMessage: "Connection failed."); return }
if case let .miFare(mifareTag) = tag {
// handle MIFARE / NTAG via NFCMiFareTag
}
guard case let .iso7816(iso7816Tag) = tag else { return }
// send APDU commands for ISO 14443-4 tags
}
}
For nfc-tag types compliant with NFC Forum (NTAG, MIFARE Ultralight), use the NFCNDEFTag protocol's writeNDEF(_:completionHandler:) after connecting via NFCTagReaderSession.
Tag Type Support Matrix
| Tag Type | Protocol | iOS Support | Read | Write |
|---|---|---|---|---|
| Type 2 (nfc-a) | ISO 14443-3A | iOS 13+ | Yes | Yes (iOS 13+) |
| Type 4A (nfc-a) | ISO 14443-4A | iOS 13+ | Yes | Yes |
| Type 4B (nfc-b) | ISO 14443-4B | iOS 13+ | Yes | Limited |
| Type 3 (FeliCa) | JIS X 6319-4 | iOS 13+ | Yes | Yes |
| Type 5 (ISO 15693) | ISO 15693 | iOS 14+ | Yes | Yes |
Limitations and Platform Differences
| Feature | iOS | Android |
|---|---|---|
| Background tag reading | iOS 14+ (NDEF only) | Yes |
| HCE (card emulation) | No (NFC Express/Secure Element only) | Yes |
| NDEF write (app open) | iOS 13+ | API 10+ |
| P2P / Beam | No | Deprecated API 28 |
| reader-writer-mode without app open | iOS 14+ (URL tags only) | Yes (intent filters) |
The most significant limitation: iOS does not support card-emulation-mode via HCE. Payment and transit card emulation requires Apple's NFC Express feature or a hardware secure element under Apple's control.
Use the NDEF Message Encoder to build test payloads and the NDEF Message Decoder to inspect tag content during development.
See also: Android NFC Programming Guide and Web NFC API Guide.
자주 묻는 질문
Core NFC tag reading (NFCTagReaderSession) requires iPhone 7 or later running iOS 11+. Background NFC tag reading without opening an app requires iPhone XS or later with iOS 12+. Writing NDEF records to tags requires iPhone 7+ with iOS 13+. MIFARE DESFire APDU commands require iOS 13+ with the NFCMiFareTag protocol. No iPad or Mac models support Core NFC.
Add the 'Near Field Communication Tag Reading' capability in Xcode (adds com.apple.developer.nfc.readersession.formats entitlement). In Info.plist, add NFCReaderUsageDescription with a user-facing string explaining why NFC is needed. For NDEF sessions, also add the application identifier list under com.apple.developer.nfc.readersession.iso7816.select-identifiers if using ISO 7816 tag sessions.
Create an NFCNDEFReaderSession with a delegate conforming to NFCNDEFReaderSessionDelegate. Implement readerSession(_:didDetectNDEFs:) to receive the array of NFCNDEFMessage objects. Each message contains NFCNDEFPayload records — use NFCNDEFPayload.wellKnownTypeURIPayload() or String(data: payload.payload, encoding: .utf8) to decode the content. Call session.begin() to activate the NFC scanning UI.
No. Apple's Core NFC framework does not expose the MIFARE Classic (Crypto-1) protocol, and iPhone hardware does not implement the proprietary Crypto-1 cipher required to authenticate with MIFARE Classic sectors. If you need to interact with MIFARE Classic cards from an iPhone, the only option is an external Bluetooth or Lightning NFC reader that handles the Crypto-1 layer itself and exposes data over a standard iOS API.
Our guides cover a range of experience levels. Getting Started guides are written for beginners with no prior NFC knowledge. Programming guides target developers integrating NFC into mobile apps or embedded systems. Security guides are for engineers designing secure NFC deployments for payments, access control, or authentication.
Most guides require only an NFC-enabled smartphone (iPhone 7+ or any modern Android device) and a few NFC tags (NTAG213 or NTAG215 recommended for beginners, available for under $1 each). Advanced guides may reference USB NFC readers like the ACR122U or Proxmark3 for development and testing.
Yes. Programming guides include code examples for Android (Kotlin/Java with the Android NFC API), iOS (Swift with Core NFC), and web-based tools (Web NFC API for Chrome on Android). All code samples are tested and include inline comments explaining each step.