Ad

Swiftui Force Update View

- 1 answer

In my content view I have a home page with some text that says "Welcome, xxxx" where xxxx is the name fetched from a firebase database. This field can be changed in the settings page that is navigated to via a Navigation Link. When the name is changed and saved the name on the home page only updates when you force shutdown the app. How do I force update the view when you press the back button from settings.

This is how I display the field:

Text("Welcome, \(companyName)")
                        .font(.system(size: 23))
                        .bold()
                        .foregroundColor(Color("background"))
                        .padding(.bottom, 50)

This is how I set a value to companyName:

func SetData() {
    
    var db = Firestore.firestore()
    let user = Auth.auth().currentUser
    let userName = user?.email ?? ""
    let docRef = db.collection("CONTACT").document(userName)
    
    docRef.getDocument { (document, error) in
        if let document = document, document.exists {
            
            //Setting Values
            let data = document.data()
            self.companyName = data?["companyName"] as? String ?? ""
            
        } else {
            print("Document does not exist")
        }
    }
    
}
Ad

Answer

There are several solutions to this, but you haven't provided enough code outlining what you have done to modify the variable companyName. The easiest solution would be to pass companyName as a binding value into the settings.

What I imagine here is that your HomeView is fetching the data on launch. In the settings, a change data request is made, but nothing is done to update the data in the HomeView. By using a binding variable we can ensure that the companyName connects to the source of truth in the HomeView, and so the function modifies the companyName which is precisely the company name on the HomeView vs. modifying potentially the value of companyName.

struct HomeView: View {
    @State var companyName = "Microsoft"
    
    var body: some View {
        NavigationView {
            NavigationLink(destination: SettingsView(companyName: $companyName)) {
                Text("Tap to navigate to Settings")
            }
        }
    }
}

struct SettingsView: View {

@Binding var companyName : String

    var body: some View {
        Button {
            SetData()
        } label: {
            HStack {
                Text("Tap to change!")
                Text("\(companyName)!")
            }
        }
    }
    
    
    func SetData() {
        
        var db = Firestore.firestore()
        let user = Auth.auth().currentUser
        let userName = user?.email ?? ""
        let docRef = db.collection("CONTACT").document(userName)
        
        docRef.getDocument { (document, error) in
            if let document = document, document.exists {
                
                //Setting Values
                let data = document.data()
                self.companyName = data?["companyName"] as? String ?? ""
                
            } else {
                print("Document does not exist")
            }
        }
    }
}

If you have already done this at it doesn't somehow work, another solution is to add an .onAppear modifier to your HomeView.

struct HomeView: View {
    @State var companyName = "Microsoft"

    var body: some View {
        VStack {
            // code ...
        }
        .onAppear {
            fetchData()
        }

    }

    func fetchData() {
        // code that returns companyFetchedName
        self.companyName = companyFetchedName
    }
}

Ad
source: stackoverflow.com
Ad