I have a model that has a myState
Bool and in a controller I sink to it like this:
model.$myState
.dropFirst()
.removeDuplicates()
.receive(on: RunLoop.main)
.sink { [weak self] myState in
print("myState: \(myState)")
}.store(in: &subs)
myState
is initialized at init as false
:
@Published private(set) var myState:Bool = false
I am trying to understand how to avoid the initial sink trigger to happen. I only want the sink to call when myState
changes value. So if in the model I set it to false when already false, I do NOT want the sink to call. I can achieve that by with the .removeDuplicates()
, but I still get the initial sink call. So then I added the .dropFirst()
. With that in I do not get the initial sink call, but, the first time I set myState
to false
(when already false) sink is called even though myState
was already false.
So, in short:
- I only want sink to trigger when
myState
changes fromfalse -> true
or fromtrue to false
- do not want sink to trigger when I setup the sink (dropFirst() works but then I get the initial duplicate edge case).
How can I setup the sink up so that it only triggers if myState
actually changes (toggles) and also not get the initial sink at setup?
CodePudding user response:
Use .scan
to pair the currently propagating value with the previously propagated value (as a tuple). You can then, in a subsequent operator, decide how to handle the tuple, letting the value proceed down the pipeline only if it consists of two different values.
CodePudding user response:
If I understand you correctly, you expect the first value to make it sink to be true
. I that is the case you simply have to swap dropFirst()
and removeDuplicates()
around:
model.$myState
.removeDuplicates()
.dropFirst()
.receive(on: RunLoop.main)
.sink { [weak self] myState in
print("myState: \(myState)")
}
.store(in: &subs)