'What is the difference between ObjectBinding and EnvironmentObject?

What is the purpose of @EnvironmentObject when we have @Binding property wrapper ? I am having trouble figuring out why @EnvironmentObject is needed. I took a look at these posting but its not quite what I am looking for EnvironmentObject in SwiftUI How to use BindableObjects (EnviromentObject)?

I also looked at their documentation which was too thin. https://developer.apple.com/documentation/swiftui/environmentobject



Solution 1:[1]

I'll try to explain generally. We have the next modifiers @State, @StateObject, @ObservedObject @Published, @EnvironmentObject and @Binding.

  1. @State - declares local value property. Apple recommends to use them as less as possible, because @State property should be used only inside the view and be responsible for a small UI things. It should have simple value type, not a reference type, otherwise it won't update the UI for you.
  2. @StateObject - declares and instantiates object instance. Usually it is your data model that should be displayed. The object must confirm ObservableObject protocol.
  3. @ObservedObject - declares a property that uses instance marked as a @StateObject that has been passed from the parent view. It is good choice when you do not want you reusable view do be dependent on the external objects. This way you passing the @StateObject directly to each child view.
  4. @EnvironmentObject - also declares a property as a @ObservedObject does, but this modifier should be used when you pass an instance to all subviews tree. To pass the instance to the child view just call YourViewToPresent().environmentObject(<your object>). And then this child view and its childs will be able to access an instance using @EnvironmentObject var instance: YourInstance without additional effort or passings. This modifier find of the declared type, so you cannot declare more than one object of the same type in the same environment. You also should be careful and do not use it too much since this may open a lot of architectural backdoors on your project(library, framework).
  5. @Published - should be used to mark ObservableObject variable to re-render the view when it's changed.
  6. @Binding - defines that the property can modify real Source of Truth(@State, @ObservedObject, @EnvironmentObject). Passing one of the properties from 1-3 points to the view you have to declare the property in child view as @Binding to create a reference. Use $ sign to pass the Source of Truth to the child: MessageDetails(message: $message). This way by changing the @Binding you will be changing actual Source of Truth. For more info recommend to watch Data Flow Through SwiftUI

Bonus: @Environment - is used to get environment values by using keyPath @Environment(\.colorScheme). You can read this value, but you cannot set this value. If the value is changed it causes UI re-render. Some values may be updated updated by SwiftUI. To find all available keys look for documentation of the EnvironmentValues. You also can override as well as add custom EnvironmentValue.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1