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