SwiftUI Use EnvironmentObject as a model for my ViewModel

Viewed 454

I have an EnvironmentObject which stores user data. After making a call to Firestore I'm filling it with data and using it everywhere. The problem occurs in my view model. I can easily retrieve data from this model but for more complex things I need to use a view model.

Can EnvironmentObject be used as a model for a view model or it should be used only for local preferences in the app, like storing some default values or preferences?

Is it better to use a separate model for my UserViewModel?

While it is very easy to access its data, It is very hard to fill it with dynamic data after making an external call for example. Especially in the SceneDelegate, where it's almost impossible because I can not make a network call there.

SceneDelegate

let userData = UserData()

Auth.auth().addStateDidChangeListener { (auth, user) in
    if user != nil {
        if let userDefaults = UserDefaults.standard.dictionary(forKey: "userDefaults") {
            userData.profile = Profile(userDefaults: userDefaults)
            userData.uid = userDefaults["uid"] as? String ?? ""
            userData.documentReference = Firestore.firestore().document(userDefaults["documentReference"] as! String)
            userData.loggedIn = true
        }
    }
}

window.rootViewController = UIHostingController(rootView: tabViewContainerView.environmentObject(userData))

UserData

final class UserData: ObservableObject {
    @Published var profile = Profile.default
    @Published var loggedIn: Bool = Auth.auth().currentUser != nil ? true : false
    @Published var uid: String = ""
    @Published var documentReference: DocumentReference = Firestore.firestore().document("")

    @Published var savedItems = [SavedItem]()

    init(document: DocumentSnapshot? = nil) {
        if let document = document {
            print("document")
        let messagesDataArray = document["saved"] as? [[String: Any]]
        let parsedMessaged = messagesDataArray?.compactMap {
            return SavedItem(dictionary: $0)
        }
        self.savedItems = parsedMessaged ?? [SavedItem]()
        }
    }

}

UserViewModel

class UserViewModel: ObservableObject {
    @Published var userData: UserData?

    init(userData: UserData? = nil) {
        self.userData = userData
    }
0 Answers
Related