CoreExtendedNFC

Swift package for NFC protocol-layer logic on iOS. CoreNFC handles RF transport; CoreExtendedNFC identifies cards, builds commands, models memory, reads passports, and exports dumps.

Capabilities

Install

dependencies: [
    .package(url: "https://github.com/Lakr233/CoreExtendedNFC.git", from: "2.1.0"),
],
targets: [
    .target(name: "App", dependencies: [
        .product(name: "CoreExtendedNFC", package: "CoreExtendedNFC"),
    ]),
]

Upgrading from 1.x? See Migrating to 2.0 and the changelog.

Quick Start

import CoreExtendedNFC

let (card, transport, session) = try await CoreExtendedNFC.scan()
print(card.type.description, card.uid.hexString)
session.invalidate()

let (info, dump) = try await CoreExtendedNFC.scanAndDump()
print(dump.exportHex())

let passport = try await CoreExtendedNFC.readPassport(
    mrzKey: "L898902C<369080619406236",
    dataGroups: [.com, .dg1, .dg2, .sod]
)

The package depends on openssl-spm for passport cryptography; SwiftPM resolves it automatically. Failures are thrown as NFCError; see Errors.

Supported Cards

FamilyIdentifyReadWriteDump
MIFARE Ultralight / EV1 / Cyesyesyesyes
NTAG 210 / 212 / 213 / 215 / 216yesyesyesyes
MIFARE DESFire EV1-EV3yesyesnofree-access files
NTAG 424 DNAas DESFire / Type 4file settings, NDEFplain filesno
FeliCa Type 3 NDEFyesyesyespartial
ISO 15693 / Type 5yesyesyesextended blocks when supported
Type 4 NDEF / ISO 7816yesyesyespartial
eMRTD / ePassportyesyesnoworkflow-specific
My Number cardyesyesnotoken data
MIFARE Classic 1K / 4Kyesnonono

MIFARE Classic is identification-only because iOS does not expose Crypto1 authentication (iOS cannot send the encrypted parity bits it needs). DESFire has no write API; NTAG 424 DNA has a plain (CommMode.Plain) WriteData only. ISO 15693 tags with more than 256 blocks are read with extended commands; tags that reject them are dumped up to block 255 and marked partially readable.

Next Steps