One of the technologies often discussed (sometimes for security reasons) is Near Field Communication (NFC). In this post, we’ll learn how to read information from an NFC tag. It’s possible to embed various types of data in a tag, such as contact information, a URL, WiFi credentials, and more, which can significantly enhance your application’s functionality.
In this example, we’ll assume that the tag contains a simple string: “Hello tag.”
To begin, once you create a project, you need to add the Near Field Communication capability. In your code, you must also import CoreNFC. After that in the info add the permission “Privacy – NFC Scan Usage Description”, if you omit this, your app will crash and you became crazy to understand the reason.
Now, let’s take a look at the main part, the NFCReader. Start by creating a file named NFCReader.swift
:
import Foundation import CoreNFC @Observable public class NFCReader: NSObject, NFCNDEFReaderSessionDelegate { public var startAlert = "Hold your iPhone near the tag." public var raw = "Raw Data will be available after scan." public var session: NFCNDEFReaderSession? public func read() { guard NFCNDEFReaderSession.readingAvailable else { print("Error") return } session = NFCNDEFReaderSession(delegate: self, queue: nil, invalidateAfterFirstRead: true) session?.alertMessage = self.startAlert session?.begin() } public func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) { DispatchQueue.main.async { if messages.count > 0, let dataMessage = String(data: messages[0].records[0].payload, encoding:.utf8) { self.raw = dataMessage } //session.invalidate() } } public func readerSessionDidBecomeActive(_ session: NFCNDEFReaderSession) { } public func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) { print("Session did invalidate with error: \(error)") self.session = nil } }
The NFCReader
is marked with the Observable
annotation, introduced in iOS 17. This feature allows SwiftUI to easily detect changes occurring within this class.
The startAlert
is the message that appears when the sheet prompting the user to move the tag near the phone is displayed. The variable raw
will contain the string read from the tag.
The NFCNDEFReaderSession
is the session used to read the tag. Note the invalidateAfterFirstRead
parameter in the constructor; if set to true, the sheet displayed for reading the tag automatically disappears once the tag is read (otherwise, we must call session.invalidate()
, see the commented code).
When the tag is read, the readSession
function is called. In this case, we retrieve the information from the first record on the tag (there could be more than one), and get the payload. It is also possible to obtain the type of the information, the typeInformationFormat
, and the tag identifier (as an exercise, I suggest displaying these pieces of information).
Finally, in the ContentView
we have:
import SwiftUI import CoreNFC struct ContentView: View { @State var NFCR = NFCReader() var body: some View { VStack(spacing: 10) { Text("NFC data: \(NFCR.raw)") Button("Read NFC") { NFCR.read() } } } }
Thus, we create the NFCReader as State so we can get the changes, tapping on the button start to read, if the things are good, the string read is displayed.
The code https://github.com/niqt/NfcExample/tree/main
Note: English is not my native language, so I apologize for any errors. I use AI solely to generate the banner of the post; the content is human-generated.
To subscribe to my newsletter [https://nicoladefilippo.com/#mailinglist]