Swift Combine prevent initial value from triggering sink and prevent duplicates at the same time?
Asked Answered
S

1

8

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 from false -> true or from true 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?

Slumgullion answered 15/11, 2022 at 21:51 Comment(0)
M
9

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)
Mummer answered 16/11, 2022 at 8:40 Comment(1)
makes sense now. Yes, this is exactly what I was doing wrong. removeDuplicates needs to go before dropFirst. Thanks.Slumgullion

© 2022 - 2024 — McMap. All rights reserved.