Multiple environmentObject

Trying to understand API calls in SwiftUI, I got some doubt about environmentObject.Here, I have a file Network.swift which contains a method to get Users. So I create an environmentObject on my ProjectNameApp.swift file (see code).But this is my question:

Let's say I have an another file Products.swift containing methods related to the products API. How I would set it in my ProjectNameApp.swift file ?

// Network.swift
import SwiftUIclass Network: ObservableObject {
    @Published var users: [User] = []    func getUsers() {
        guard let url = URL(string: "https://jsonplaceholder.typicode.com/users") else { fatalError("Missing URL") }        let urlRequest = URLRequest(url: url)        let dataTask = URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in
            if let error = error {
                print("Request error: ", error)
                return
            }            guard let response = response as? HTTPURLResponse else { return }            if response.statusCode == 200 {
                guard let data = data else { return }
                DispatchQueue.main.async {
                    do {
                        let decodedUsers = try JSONDecoder().decode([User].self, from: data)
                        self.users = decodedUsers
                    } catch let error {
                        print("Error decoding: ", error)
                    }
                }
            }
        }        dataTask.resume()
    }
}

// ProjectNameApp.swift@main
struct ProjectNameApp: App {
    var network = Network()    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(network)
        }
    }
}

Would be the right implementation something like this ? For each API group a new environmentObject ?

// ProjectNameApp.swift@main
struct ProjectNameApp: App {
    var network = Network()
    var product = Product()    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(network)
                .environmentObject(product)
        }
    }
}

Thank you

Answered by ForumsContributor in
Accepted Answer

I would have a single DataModel class (ObservableObject), which has your published vars for users and product.

It then has functions to (e.g. getUsers) to set/update your published vars. The network call is done within the DataModel class.

To promulgate a single version of the DataModel in your app, throughout the View hierarchy, you need to put @StateObject var dataModel = DataModel() in your ProjectNameApp instead of var network... Then have .environmentObject(dataModel) after ContentView()

In subsequent views (e.g. ContentView) where you want to have access to dataModel put @EnvironmentObject var dataModel: DataModel after the struct definition.

Within your SwiftUI Views, you can then use references to your model vars, e.g. dataModel.product

If you always need to get the users, and before anything else happens, then you can put a call to getUsers() in the DataModel init(). If you don't do it this way then you'll need a call to dataModel.getUsers() somewhere else.

Regards, Michaela

Multiple environmentObject
 
 
Q