CoreNFC on iOS is a powerful but low-level framework that exposes NFC tag communication at the transport layer, leaving developers to implement the higher-level protocol logic themselves. CoreExtendedNFC addresses this gap by porting the protocol-layer intelligence of libnfc to iOS, providing a comprehensive Swift package that supports multiple NFC tag types and advanced features like passport reading and secure messaging.
what CoreExtendedNFC does and how it’s built
CoreExtendedNFC is a Swift Package designed to extend Apple’s CoreNFC framework by adding the protocol-layer functionality that CoreNFC itself lacks. Apple’s CoreNFC provides access to NFC tags by handling the physical and transport layers, but higher-level operations such as tag type identification, memory read/write, and secure messaging protocols must be implemented by the developer.
This package bridges that gap by implementing protocol logic for over 25 card types, including Ultralight, NTAG, DESFire, FeliCa, ISO 15693, and Type 4 tags. It supports reading and writing memory, dumping tag contents, and advanced DESFire application layer features like Additional Frame chaining. Beyond the usual tag support, it also implements eMRTD passport reading with BAC key exchange and Secure Messaging, plus support for Japanese My Number cards.
Architecturally, CoreExtendedNFC isolates CoreNFC dependencies to a single Transport layer. This abstraction wraps CoreNFC’s tag session and communication, while all protocol logic is implemented in pure Swift in other layers. This design means the core NFC logic is platform-agnostic and can be fully unit-tested using a MockTransport implementation without requiring NFC hardware.
The package includes built-in cryptographic primitives such as CRC_A/B, AES-CMAC, 3DES, and ISO 9797-1 MAC algorithms, which removes the need for external dependencies. It targets iOS 15 and above, requires Swift 6.2 or newer, and Xcode 16 or later.
The repo includes an extensive test suite with 319 tests across 30 suites, covering protocol compliance with public standards sourced from ICAO 9303, NIST FIPS, and NXP datasheets.
what sets CoreExtendedNFC apart and tradeoffs
The standout feature of CoreExtendedNFC is how it cleanly separates platform-specific NFC transport from pure Swift protocol logic. By limiting CoreNFC imports to a single Transport layer, it makes the complex NFC protocol code testable without hardware and easier to maintain. This pattern is rare in iOS NFC tooling, where many libraries mix transport and protocol logic.
Supporting 25+ card types and detailed protocol features like DESFire Additional Frame chaining and eMRTD BAC key exchange is ambitious. The code quality appears high, with comprehensive tests and public standard test vectors ensuring correctness.
Including cryptographic primitives directly in the package is a pragmatic choice that avoids external dependencies and potential compatibility issues.
The tradeoff is that the package requires iOS 15+, Swift 6.2+, and Xcode 16+, which may limit adoption on older projects. Also, while the package abstracts many NFC protocols, NFC on iOS remains limited by CoreNFC capabilities and hardware constraints. Some edge cases or newer tag types might not be supported yet.
From a developer experience perspective, the package offers high-level APIs for scanning, identifying, dumping, and reading passports. However, NFC development on iOS demands careful setup of capabilities and Info.plist keys, which the repo documents well.
quick start with CoreExtendedNFC
The repo’s README provides straightforward usage examples that demonstrate scanning, identifying, dumping NFC tags, and reading e-passports with MRZ keys.
import CoreExtendedNFC
// Scan and identify
let (card, transport, session) = try await CoreExtendedNFC.scan()
print(card.type.description, card.uid.hexString)
session.invalidate(message: "Done")
// Scan and dump
let (info, dump) = try await CoreExtendedNFC.scanAndDump()
print(dump.exportHex())
// Read a passport
let passport = try await CoreExtendedNFC.readPassport(
mrzKey: "L898902C<3640812512041598",
dataGroups: [.dg1, .dg2]
)
print(passport.mrz?.surname ?? "?")
Installation requires adding the package dependency in your Swift Package Manager configuration:
dependencies: [
.package(url: "https://github.com/Lakr233/CoreExtendedNFC.git", from: "0.1.0"),
]
Your app must enable NFC Tag Reading capability and configure relevant Info.plist entries, including NFCReaderUsageDescription and com.apple.developer.nfc.readersession.formats set to TAG. The repo’s documentation and example project help with these setup steps.
verdict: who should consider CoreExtendedNFC
CoreExtendedNFC is a solid option if you need protocol-level NFC functionality on iOS beyond what CoreNFC offers natively. Its architecture is particularly appealing for developers who value clean separation of concerns and testability in NFC protocol implementations.
It’s relevant for projects dealing with a variety of NFC tag types, especially where DESFire, FeliCa, ISO 15693, or passport reading are involved. The inclusion of cryptographic primitives and detailed test coverage signals production readiness.
However, it demands iOS 15+ and the latest Swift/Xcode tooling, so legacy support is limited. The domain remains constrained by Apple’s CoreNFC API surface and hardware capabilities, so the package can’t work magic beyond those limits.
In practice, CoreExtendedNFC can save significant development time and effort when building robust NFC features on iOS with protocol-level control and high confidence in correctness. For iOS developers tackling complex NFC use cases, it’s worth exploring.
The repo is well documented, tested, and maintained, making it a practical choice for serious NFC app development on iOS.
→ GitHub Repo: Lakr233/CoreExtendedNFC ⭐ 235 · Swift