Im learning about SwiftUI
for macOS development, and Im wondering what would be the right approach when creating Managers, services etc. These are objects not related to the UI - strictly business logic things, not even ViewModels
. Should I not use things like ObservableObject
, Published
, AppStorage
, etc. in this kind of classes? On one hand it seems to be beneficial to add this, so that I can later easily use them with ViewModels
, and bind directly to some properties. On the other hand it seems wrong - like these property wrappers are strictly SwiftUI
related. So should I resign from these things in managers, services and other business logic objects?
CodePudding user response:
Both ObservableObject
and Published
are defined in Combine, so they are fine to use outside of the UI layer of your app. On the contrary, @AppStorage
is defined in SwiftUI, so you should only use it in View
s.
However, the fact that something is defined in Combine doesn't necessarily mean that it provides meaningful value to use when not binding to your UI.
ObservableObject
's main use case is storing objects as @ObservedObject
on a View
and getting automatic view updates. Even though you could consume the objectWillChange
Publisher
that ObservableObject
provides from outside a view, there's not much use for it, so in general, I wouldn't advice on making objects conform to ObservableObject
unless they are directly updating your SwiftUI views.
@Published
on the other hand provides significant value even outside your ViewModel-View interaction. Observing changes to mutable state is quite useful even in a pure business logic layer, such as exposing the current location of the user in a location manager class and observing it from a view model. Marking this property @Published
makes it much easier to observe.
The separation of what objects a View should directly access is a subjective topic, so I won't go into that in much detail, but if you want to keep your View independent of your business logic objects other than the ViewModel, you should store managers, services, etc on your ViewModel and proxy any properties that need to update the UI through the ViewModel. For this to work, you don't need to make your managers/services conform to ObservableObject
, however, storing mutable state as @Published
can be quite helpful.
CodePudding user response:
ObservableObject
allows you to store state in an object that is independent from any views. When you conform your class to ObservableObject
then views can observe it (or listen). To broadcast (publish) values of your variables to the views, just mark them with property wrapper @Published
. Obviously, you know that.
I consider this pattern as strictly dedicated to Object->Views communication.