0

I am trying to declare a global variable, which to my knowledge can be declared in any file as such:

struct globalVariable{
    public var usrName = ""
}

This is declared in my root View. I want to update that variable when a user logs into the application, this global variable will be updated with the log in user's user name. I want to do the update in the following function in an authentication file.

func login(username: String, password: String) {
      
    self.isAuthenticating = true
      
      //Open database for validation
      let userDB = UserDatabase().createDB()
      
      <------ Update the global variable to the passed in userName
      
      
      //Open Database for filtering
      //let photoDB = DbHelper().getPictures(usrName: username)
      
      if checkUser(db: userDB,un: username,pw: password) == true {
          print("Login Succeeded")
          // emulate a short delay when authenticating
          DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
            self.isAuthenticating = false
            self.needsAuthentication = false
          }
      }else {
         print("Login Failed")
      }
  }

After updating the file, I want to pass this value into a function that is called in my content view as such:

import SwiftUI



struct ContentView: View {
    
    @EnvironmentObject var authenticator: Authenticator
    
    @State private var rating: Int = 0
    
    
    var pictureURL = DbHelper().getPictures()  <-- Pass in global Variable
    
    
    var body: some View {
        List(pictureURL, id: \.self) { photo in
            VStack{
                if #available(iOS 15.0, *) {
                    AsyncImage(url: URL(string: photo), scale: 10.0)
                } else {
                    // Fallback on earlier versions
                }
                RatingView(rating: $rating)
            }
        }
        Button("Logout") {
            authenticator.logout()
        }
    }
}


struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
            .environmentObject(Authenticator())
    }
}

How would I go about solving this with global variables?

1 Answer 1

2

I would suggest you use dependency injection instead of trying to use a "global" variable.

change

struct globalVariable{
    public var usrName = ""
}

into

class GlobalModel: ObservableObject {
    @Published var usrName = ""
}

Set it in your upper app hierarchy like this:

@StateObject var globalModel = GlobalModel()

and pass it around the views that need it, for example using,

.environmentObject(globalModel)
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you for the help. Though I think I am putting the Environment Variable in the wrong place. In what view would I pass around using environmentObject(globalModel())? I put it in the View I need it in, should I put it in my root view?
Ok, I think I set it up correctly, the only problem I am having now is I can't pass it into the function. It states: Cannot use instance member 'model' within property initializer; property initializers run before 'self' is available. How do I solve this?
read up on how to use ObservableObject passing using environmentObject, there are plenty of good tutorials and answers on SO. Don't use it in functions, all is already done for you when you useenvironmentObject.
Sorry to bug but can you link any tutorials? I am kind of lost, maybe I should read how these mechanisms work
yes, study these concepts, there are often used and important in using swiftui properly. Google the words, you'll find something.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.