iosswiftnfcmifarecore-nfc

Detect ISO/IEC 14443 (Mifare Ultralight or Classic) NFC Cards with CoreNFC


I was at the WWDC and was able to detect NFC Cards provided by Apple Labs with the following code:

nfcSession = NFCNDEFReaderSession(delegate: self, queue: nil, invalidateAfterFirstRead: false)
nfcSession.begin()

And the delegate methods:

func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) {
    DispatchQueue.main.async {
        print("Error:" + error.localizedDescription)
    }
}

func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) {
    print("Did detect NDEFs.")
    for message in messages {
        for record in message.records {
            print(record.identifier)
            print(record.payload)
            print(record.type)
            print(record.typeNameFormat)
        }
    }
}

However, I want to detect a Mifare Ultralight (or classic) card under the ISO/IEC 14443 protocol.

Whenever I get the Scan View, nothing happens, neither the error callback nor the success block gets called. Is there a way to read these cards?

Thanks a lot!


Solution

  • The MIFARE Classic 1k or 4k chips predate the ISO/IEC 14443 standard. In the WWDC CoreNFC presentation, MIFARE Classic is not explicitly mentioned to be supported by CoreNFC.

    MIFARE Ultralight is supported, or any other Type 2 Tag (e.g. NTAG 203). The successor of MIFARE Classic would be Type 4 (DESFire), I think.

    Having said this, I could successfully read a MIFARE Classic 1k Tag, if all of the 16 sector keys A&B are left at the factory default, and if the tag contains a valid NDEF message. If even one key is changed, the reader aborts with readerSessionInvalidationErrorUserCanceled.

    Beta 2 is a lot more reliable when reading tags, in my experience. On my phone, the very first read always fails, and I have to stop and restart the reader session. From then on, it works fine. With beta 1, I often had to reboot the phone first, and even then hat to cancel/retry many times.

    EDIT: NXP - the vendor of MIFARE Tags - has published a specification that explains how to store NDEF tags inside of a MIFARE classic tag. My tests show that such tags can be read with the CoreNFC library without problems. Adafruit has published a library for Arduino that allows to reformat a MIFARE classic tag according to this specification.

    Earlier I used another NDEF Arduino library that used a different approach, not in-line with the specification. Sometimes the tags could be read anyway, but not reliably.

    In conclusion: Make 100% sure that you use a tag that is formatted according to the published specifications. If you can't read a tag that you found in your drawer, it's probably not the fault of the CoreNFC library.