Errors
Every failure the library throws is an NFCError. It is Sendable, Equatable and a LocalizedError with localized descriptions, so apps can match on cases instead of message text.
Cancellation
do {
let (info, dump) = try await CoreExtendedNFC.scanAndDump()
} catch where error.isNFCCancellation {
// User dismissed the sheet, task cancelled, or the app ended the scan: stay silent.
} catch {
showAlert(error.localizedDescription)
}
Error.isNFCCancellation is true for NFCError.userCanceled, CancellationError and NFCError.sessionInvalidatedByCaller. NFCError.isUserCancellation is true only for .userCanceled. After the user dismisses the sheet, later session-loss failures from that session's transports are reported as .userCanceled. NFCSessionManager.wasCanceledByUser covers a failure that raced the cancel.
Cases
| Case | Meaning |
|---|---|
nfcNotAvailable | The device has no NFC tag reading. |
sessionTimeout | The reader session hit the system time limit. |
tagConnectionLost | The tag left the field or stopped answering. |
tagNotSupported | No flow exists for this card: no dump flow, no NDEF path, NDEF formatting on Type 3/4, or a transit card no reader recognizes. |
sessionInvalidated(String) | The session ended for a reason without a dedicated case; the text is the system's description. |
userCanceled | The user dismissed the NFC sheet. |
systemBusy | Another reader session holds the NFC hardware. |
sessionInvalidatedByCaller | The app ended a pending scan with invalidate() or invalidate(errorMessage:). |
scanInProgress | scan was called while another scan on the same NFCSessionManager was still waiting for a tag. |
crcMismatch | A tag response failed its RF frame CRC. |
checksumMismatch | A checksum carried in card data did not match, for example the Type 3 Tag Attribute Information Block. |
invalidResponse(Data) | The tag's response was malformed or too short. |
unexpectedStatusWord(UInt8, UInt8) | An ISO 7816 status word the operation does not accept. |
responseChainTooLong(maxFrames:) | The card kept asking for more response frames (61xx, 91AF) past the limit. |
applicationNotFound(aid:) | SELECT by AID was answered with "not found" (6A82, 6A86, 6999, ...). See ResponseAPDU.isApplicationNotFound. |
iso15693Error(code:) | An ISO 15693 error code other than 0x12 / 0x14 (block locked), for example 0x10 block not available. |
authenticationFailed | Authentication with the tag failed. |
pinVerificationFailed(remainingAttempts:) | VERIFY was refused or the PIN is blocked; 0 when blocked, nil when the card did not say. |
pinRequired(MyNumberPINType) | The operation needs this PIN but none was supplied. |
writeFailed(page:) | The tag did not acknowledge a page write. |
tagLocked | The tag or block denies writing: Type 2/4/5 CC write access, a Type 3 Attribute Information Block whose RWFlag is not 01h, ISO 15693 codes 0x12 / 0x14, Type 4 UPDATE BINARY 6982 / 6985. |
irreversibleWriteRefused(page:) | A write to a lock, OTP, configuration, password or key page was refused before anything was sent, because the caller did not pass allowIrreversible: true. |
tagNotNDEFFormatted | No NDEF Capability Container or NDEF Tag Application; format the tag first. |
ndefMessageNotFound | The tag is NDEF formatted but holds no NDEF message, or only an empty one (for example after erasing it with writeNDEF and no records). Raised on every NDEF family. |
ndefCapacityExceeded(required:capacity:) | The encoded message does not fit the tag's NDEF area. |
desfireError(DESFireStatus) | A DESFire native status other than success. |
felicaBlockReadFailed(statusFlag:) / felicaBlockWriteFailed(statusFlag:) | A FeliCa block command returned a non-zero status flag. |
bacFailed(String) | BAC or the plain eMRTD application SELECT before BAC failed. |
secureMessagingError(String) | Secure Messaging or PACE failed, or the chip refused the protected eMRTD application SELECT after PACE with a protected status (a plain status word surfaces as unexpectedStatusWord). |
dataGroupNotAvailable(String) / dataGroupParseFailed(String) | An eMRTD file is absent or protected, or could not be parsed. |
cryptoError(String) | A cryptographic operation failed. |
notOperableOnIOS(CardType) | iOS cannot operate this card type, for example MIFARE Classic. |
unsupportedOperation(String) | The operation does not apply to this transport or card, or the library refused it. |
invalidParameter(String) | An argument is out of range or malformed, for example a DESFire AID that is not 3 bytes. |
malformedDump(String) | A memory dump being exported or imported is malformed or inconsistent. |