Search code examples
swiftuiobservedobjectenvironmentobject

SwiftUI How to pass a global variable to non-View classes


I understand how to use @EnvironmentObject to make global data available to any view class, but I can't find a way to pass the variable to a non-view class.

My situation, which seems like a common issue, is:

  1. Login, returns an access token. This token is required to be used in all subsequent api calls
  2. Store access token in a UserSettings class
  3. Place the UserSettings in an Environment bucket
    let contentView = ContentView()
        .environmentObject(UserSettings())
  1. Each view will display data based on the data returned in an api call
struct HomeView: View {
    @EnvironmentObject var user: UserSettings  <=== ACCESS TO GLOBAL DATA
    @ObservedObject var categories = Categories()  <=== GET DATA FOR THIS VIEW

    var body: some View {
    ...
}
  1. Categories() is a non-view Swift class that will retrieve the data, but requires the access token which is stored in UserSettings
class Categories : ObservableObject {
    @Published var allCategories = CategoriesModel()
    @EnvironmentObject var user: UserSettings  <==== CANNOT ACCESS THIS DATA!

    init() {
        fetchCategories(page: 0, pageSize: 20)
    }

UserSettings is empty because this class is not a View struct and doesn't seem to behave like a View class would. Since the access token I need is stored in the UserSettings class, how can I get access to this? Is there an alternative way to store/access this data?


Solution

  • Use a Singleton Pattern. Call UserSettings.sharedInstance from Categories & let contentView = ContentView().environmentObject(UserSettings.sharedInstance)

    https://developer.apple.com/documentation/swift/cocoa_design_patterns/managing_a_shared_resource_using_a_singleton