Problems updating a variable

Hey everyone! So I've been creating a program to extract the UID (unique identifier) from an NFC Tag and have been stuck on this very last problem: On the third line I created a variable which I want to be able to change called tagUID, initially just "UID". If you look down to the very last line of code, you see that (if there is a connection to the tag) the last thing it's supposed to do is change the state of tagUID to whatever the UID of the tag is, but it's refusing to do so. Everything else works great its only not changing that variable!

class NFCReader: NSObject, ObservableObject, NFCTagReaderSessionDelegate {

    @State var tagUID = "UID"

    var session: NFCTagReaderSession?

    func activate() {

    self.session = NFCTagReaderSession(pollingOption: .iso14443, delegate: self)

    self.session?.alertMessage = "Hold Your Phone Near the NFC Tag"

    self.session?.begin()

    }

func tagReaderSessionDidBecomeActive(_ session: NFCTagReaderSession) {

    print("Session Begun!")

}

func tagReaderSession(_ session: NFCTagReaderSession, didInvalidateWithError error: Error) {

    print("Error with Launching Session")

}

func tagReaderSession(_ session: NFCTagReaderSession, didDetect tags: [NFCTag]) {

 print("Connecting To Tag")

    if tags.count > 1{

        session.alertMessage = "More Than One Tag Detected, Please try again"

        session.invalidate()

    }

    let tag = tags.first!

    session.connect(to: tag) { [self] (error) in

        if nil != error{

            session.invalidate(errorMessage: "Connection Failed")

        }

        if case let .miFare(sTag) = tag{

            let UID = sTag.identifier.map{ String(format: "%.2hhx", $0)}.joined()

            print("UID:", UID)

            print(sTag.identifier)

            session.alertMessage = "UID Captured"

            session.invalidate()

            DispatchQueue.main.async {

                self.tagUID = "\(UID)"

            }

            tagUID = "\(UID)"

        }

        

    }



}

   

}

You are declaring "tagUID" in a class, so you should not be using the @State property wrapper (which is for SwiftUI).

Try removing the "@State"... just use:

var tagUID = "UID"

Or since your NFCReader is an ObservableObject, you may mean:

@Published var tagUID = "UID"

The problem now, is that when you activate your NFCReader, it does not immediately return the tag...
...so you can not immediately assign reader.tagUID

To solve this, in NFCReader we can "Publish" the tagCode...
...and in the View, we show this published value.
Then, when NFCReader gets the tagCode, it will automatically update your SwiftUI View.

Try this:

import SwiftUI
import CoreNFC

struct ContentView: View {
    @StateObject private var reader = NFCReader()

    var body: some View {
        VStack{
            Text(reader.tagUID)
            Button {
                reader.activate()
            } label: {
                Text("Scan")
                .font(.title)
                
            }.padding()
            
        }
    }
}

class NFCReader: NSObject, ObservableObject, NFCTagReaderSessionDelegate {
    @Published var tagUID = "UID"
    var session: NFCTagReaderSession?
    
    func activate() {
        self.session = NFCTagReaderSession(pollingOption: .iso14443, delegate: self)
        self.session?.alertMessage = "Hold Your Phone Near the NFC Tag"
        self.session?.begin()
    }
    
    func tagReaderSessionDidBecomeActive(_ session: NFCTagReaderSession) {
        print("Session Begun!")
    }
    
    func tagReaderSession(_ session: NFCTagReaderSession, didInvalidateWithError error: Error) {
        print("Error with Launching Session")
    }
    
    func tagReaderSession(_ session: NFCTagReaderSession, didDetect tags: [NFCTag]) {
        print("Connecting To Tag")
        if tags.count > 1{
            session.alertMessage = "More Than One Tag Detected, Please try again"
            session.invalidate()
        }
        let tag = tags.first!
        session.connect(to: tag) { [self] (error) in
            if nil != error{
                session.invalidate(errorMessage: "Connection Failed")
            }
            if case let .miFare(sTag) = tag{
                let UID = sTag.identifier.map{ String(format: "%.2hhx", $0)}.joined()
                print("UID: \(UID)")
                print(sTag.identifier)
                session.alertMessage = "UID Captured"
                session.invalidate()
                DispatchQueue.main.async {
                    self.tagUID = "\(UID)"
                }
            }
        }
    }
}

Did that help you, @00ri?

Problems updating a variable
 
 
Q