Home > OS >  How can I update the view when the app is done scanning for NFC?
How can I update the view when the app is done scanning for NFC?

Time:01-31

I have a Swift application that reads from an NFC card. I want it to show the data it read on the screen, which I am able to do if I have a button that checks for updated data using the getDetected() function. I want to, however, update the view when it is done reading the NFC tag so I can immediately display the data. How can I do this?

NFC Reader class:

import Foundation
import CoreNFC

class NFCReader: NSObject, NFCNDEFReaderSessionDelegate {
    var detected = [NFCNDEFMessage]()
    var session: NFCNDEFReaderSession?
    func beginScanning() {
        guard NFCNDEFReaderSession.readingAvailable else { return }
        session = NFCNDEFReaderSession(delegate: self, queue: nil, invalidateAfterFirstRead: true)
        session?.alertMessage = "Hold your iPhone near the reader to unlock."
        session?.begin()
    }
    func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) {
        self.detected = messages
        self.session = nil
    }
    func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) {
        self.session = nil
    }
    func getDetected() -> [NFCNDEFMessage] {
        return detected
    }
}

CodePudding user response:

you could try the following approach, using a ObservableObject. Whenever the @Published var detected is changed, the UI will be updated.

class NFCReader: NSObject, NFCNDEFReaderSessionDelegate, ObservableObject { // <--- here
    @Published var detected = [NFCNDEFMessage]()  // <--- here
    
    var session: NFCNDEFReaderSession?
    
    func beginScanning() {
        guard NFCNDEFReaderSession.readingAvailable else { return }
        session = NFCNDEFReaderSession(delegate: self, queue: nil, invalidateAfterFirstRead: true)
        session?.alertMessage = "Hold your iPhone near the reader to unlock."
        session?.begin()
    }
    
    func readerSession(_ session: NFCNDEFReaderSession, didDetectNDEFs messages: [NFCNDEFMessage]) {
        self.detected = messages
        self.session = nil
    }
    
    func readerSession(_ session: NFCNDEFReaderSession, didInvalidateWithError error: Error) {
        self.session = nil
    }
    
    // no real need for this
    func getDetected() -> [NFCNDEFMessage] {
        return detected
    }
    
}


struct ContentView: View {
    @StateObject var readerNFC = NFCReader()  // <-- here
    
    var body: some View {
        ForEach(readerNFC.detected, id: \.self) { msg in
           //     .....
        }
    }
    
}
  •  Tags:  
  • Related