Search code examples
iosnfccore-nfc

CoreNFC - Empty NDEF after upgrade to iOS16


I've just updated to iOS 16, and all of a sudden the same code I used in iOS 15 is now reading ndefMessage as nil in the didDetect callback. I can't find anything online regarding what in iOS 16 would cause this, has anyone seen anything similar?

When I scan the same tag on Android, or use the NFC Tools app on iOS, I can read the tag NDEF fine. It seems that just my code seems to have been affected by the update...

UPDATE 1: I have put the same code onto my iOS 15.6 device, and it works perfectly. It seems to me that this is an iOS 16 bug.

Here's what I have:

func readerSession(_ session: NFCNDEFReaderSession, didDetect tags: [NFCNDEFTag]) {
    print("did detect")
    let str: String = nfcWriteContent
    if (tags.count > 1) {
        let retryInterval = DispatchTimeInterval.milliseconds(500)
        session.alertMessage = "too_many_nfc_detected".localized()
        DispatchQueue.global().asyncAfter(deadline: .now() + retryInterval, execute: {
            session.restartPolling()
        })
        return
    }
    
    let tag = tags.first!
    
    print("reading...")
    tag.readNDEF(completionHandler: {(ndefMessage: NFCNDEFMessage?, error: Error?) in
        var res = ""
        
        if (ndefMessage == nil) {
            // EVERY NFC SCAN ALWAYS FALLS IN HERE NOW
            // WHEN SCANNING THE SAME TAG ON ANDROID, NDEF CONTENT IS PROPERLY RETURNED
            print("empty tag")
        } else {
            print (ndefMessage!.records.count)
            for payload in ndefMessage!.records {
                if (payload.payload.count == 0) {
                    continue
                }
                res += (String.init(data: payload.payload.advanced(by: 1), encoding: .utf8) ?? "Format not supported")
            }
        }
        
        session.alertMessage = "tag_successfully_read".localized()
        session.invalidate()
        print("read \(res)")
    })
            
}

Solution

  • I got feedback from an Apple engineer. The sample project runs fine on iOS 16. You are missing out that you are not connected to the tag:

    try await ndefReaderSession?.connect(to: tag)
    let message = try await tag.readNDEF()
    
    or
    
    ndefReaderSession?.connect(to: tag) { error in
        //call tag.readNDEF here   
    }