3

So 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)
        }
    }
}

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

Whenever I get the Scan View, nothing happens. Nor the error callback or the success block get called. Is there a way to read this cards?

Thanks a lot!

David Cruz
  • 2,995
  • 3
  • 28
  • 41
  • The new iOS 13 Beta changed a lot, you're now able to directly access mifare tags https://developer.apple.com/documentation/corenfc/nfcmifaretag – wiomoc Jun 06 '19 at 20:46
  • @wiomoc yes, I tried the new CoreNFC of iOS13 (see [this answer](https://stackoverflow.com/a/58482490)) but it seems to support/allow only tag types mentioned in the [NFC MiFare Family](https://developer.apple.com/documentation/corenfc/nfcmifarefamily) API, whereas the `unknown` family member does not seem to refer the MIFARE Classic (Emulation) ICs – krevelen Oct 21 '19 at 09:08

2 Answers2

9

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.

  • Thanks Martin - two comments: 1.) DESFire is one implementation of Type 4 tags; they are not direct successors of MIFARE Classic. 2.) it would be bad practice to leave all keys unchanged, as the NDEF could be changed by anyone with a NFC Writing Device (such as an Android Phone). So, it is definitely better to use tags that can be locked. – ErikM Jun 26 '17 at 19:47
  • Thanks for your comment! My remarks about encryption keys were wrong anyway. The NDEF spec demands that key A is changed to a value specific for NDEF usage. My generic Arduino reader did not check for these non-factory-default keys, and reported the tag as unreadable. At the same time, the iPhone could not read the tag, but probably because it was not 100% properly formatted for NDEF. I wrongly concluded that the keys are the reason for the read failure. –  Jun 27 '17 at 13:42
2

You can have a look at e.g. https://github.com/hansemannn/iOS11-NFC-Example or other tutorials (http://jamesonquave.com/blog/core-nfc-tutorial-for-nfc-on-ios-devices/) that talk about using NFC with iOS. Some observations: Your first code snippet shows NFCISO15693ReaderSession instead of NFCNDEFReaderSession.

On top you need to ensure that your tags/cards contain a valid NDEF Message. My observation so far is:

  • No NDEF on tag --> no action on the iPhone
  • Invalid NDEF on tag need to be properly handled within your app and lead to a crash in worst case.
ErikM
  • 591
  • 1
  • 4
  • 13