Search code examples
swiftreactive-programmingcombine

Setting an @Published var to nil after no more events are received


Consider the following code:

class MyController: NSObject, ObservableObject {

    //...

    @Published var myRapidlyChangingVar: MyEnum? = nil

    //...

    func calledAtHighFrequencyByExternalEvents(value: MyEnum) {
        myRapidlyChangingVar = value
    }
}

The value of myRapidlyChangingVar needs to be set to nil if no calls to calledAtHighFrequencyByExternalEvents() have been made for 1 second.

What is the simplest and cleanest approach to adopt to achieve this?

Strikes me as the sort of thing which Reactive programming should make incredibly simple, but unsure where to start or what to search for.


Solution

  • You can easily achive this with a debounce(for:scheduler:options:)

    let cancellable = myRapidlyChangingVar
        .compactMap { $0 }
        .debounce(for: .seconds(1), scheduler: DispatchQueue.main)
        .sink { [weak self] _ in self?.myRapidlyChangingVar = nil }
    }
    

    Debounce has a fairly similar sibiling throttle(for:scheduler:latest:)

    You can read more about both in this blogpost.