30
votes

If the entire views access the same model in an app, I think the Singleton pattern is enough. Am I right?

For example, if MainView and ChildView access the same model(e.g. AppSetting) like below, I cannot find any reason to use EnvironmentObject instead of the Singleton pattern. Is there any problem if I use like this? If it is okay, then when I should use EnvironmentObject instead of the Singleton pattern?

class AppSetting: ObservableObject {
    static let shared = AppSetting()
    private init() {}

    @Published var userName: String = "StackOverflow"
}
struct MainView: View {
    @ObservedObject private var appSetting = AppSetting.shared

    var body: some View {
        Text(appSetting.userName)
    }
}
struct ChildView: View {
    @ObservedObject private var appSetting = AppSetting.shared

    var body: some View {
        Text(appSetting.userName)
    }
}

Thanks in advance.

2
The only problem is that you made it available for every type/function in your application. - Tony

2 Answers

16
votes

You are correct there is no reason in this case to use an EnvironmentObject. Apple even encourages to make no excessive use of EnvironmentObjects.

Nevertheless an EnvironmentObject can be great too, if you use an object in many views, because then you don't have to pass it from View A to B, from B to C and so on.

Often you find yourself in a situation where even @State and @Binding will be enough to share and update data in a view and between two views.

0
votes

I think when your app supports multiple windows via Scene (example Document based apps) maybe the singleton is not a solution and the EnvironmentObject is better. Example you want to share selectedColor. When you use a singleton, the selectedColor will be same in entire app, in every scene (in every view in window). But if you want to use separated settings the EnvironmentObject is convenient.