Reputation: 14060
I have a Swift Combine question. Let’s say I have an ObservableObject
with a few properties like this:
class AppState: ObservableObject{
static let shared = AppState()
@Published var a: Object?
@Published var b: Object?
@Published var c = [Object]()
}
I know I can be notified if a single object changes like this:
myCancellable = AppState.shared.$a.sink { a in
//Object 'a' changed
}
But is there a way to watch multiple properties and respond if any of them change?
Something like:
myCancellable = AppState.shared.[$a, $b, $c].sink { a, b, c in
//Objects 'a', 'b', or 'c' changed
}
Upvotes: 1
Views: 1567
Reputation: 14060
Thanks for the great answers. Another idea I stumbled across was to just store my objects in a struct
and observe that.
struct Stuff{
var a: Object?
var b: Object?
var c = [Object]()
}
Then in my AppState
class:
class AppState: ObservableObject{
static let shared = AppState()
@Published var stuff: Stuff!
}
Then in the publisher:
myCancellable = AppState.shared.$stuff.sink { stuff in
print(stuff.a)
print(stuff.b)
print(stuff.c)
}
I like this approach since I don't want to observe everything that might change in the AppState
class (which is probably an indication I should break it into smaller pieces). This seems to be working well so far.
Upvotes: 0
Reputation: 52312
Assuming that a
, b
, and c
are the same type (which Asperi pointed out to me they are not in the example, since c
is an array), you can use Publishers.MergeMany
:
myCancellable = Publishers.MergeMany([$a,$b,$c]).sink { newValue in
}
There are also more specific versions of this function for a set number of arguments. For example, in your case, you could use Publishers.Merge3
Often, in examples I've seen online, you'll see Publishers.MergeMany
followed by collect()
, which gathers results from all of the publishers before moving on, publishing the results as an array. From your question, though, it doesn't sound like this will meet your needs, as you want a notification each time a singular member changes.
Upvotes: 2
Reputation: 257493
The possible variant is to observe any published changes of entire object, like
myCancellable = AppState.shared
.objectWillChange.sink {
// react here
}
Upvotes: 1