I'd like to create a repeat functionality that creates a loop in my code using Combine. I noticed that Combine does not have a repeat publisher via this great repo: https://github.com/freak4pc/rxswift-to-combine-cheatsheet. Heres the code that I wrote that works to repeat 2 states. How do I reduce this to something more readable or create my own repeat function?
toggleShouldDisplay = Just<Void>(())
.delay(for: 2, scheduler:RunLoop.main)
.map({ _ in
self.shouldDisplay = true
self.didChange.send(())
})
.delay(for: 2, scheduler: RunLoop.main)
.map({ _ in
self.shouldDisplay = false
self.didChange.send(())
})
.setFailureType(to: NSError.self)
.tryMap({ _ in
throw NSError()
})
.retry(.max) // I might hit Int.max if I reduce the delays
.sink(receiveValue: { _ in
//Left empty
})
The .retry(_:)
operator is really intended to be used for retrying operations that can fail, such as network requests. It sounds like you need a timer instead. Luckily, as of Xcode 11 beta 2, Apple has added Publisher support to the Timer
class in Foundation.
One other comment about your implementation: I assume this code is used in a BindableObject
because you are accessing didChange
. Since didChange
can be any kind of Publisher
, why not use your shouldDisplay
property as the Publisher
?
final class MyModel: BindableObject {
var didChange: CurrentValueSubject<Bool, Never> { shouldDisplaySubject }
var shouldDisplay: Bool { shouldDisplaySubject.value }
private let shouldDisplaySubject = CurrentValueSubject<Bool, Never>(false)
private var cancellables: Set<AnyCancellable> = []
init() {
startTimer()
}
private func startTimer() {
Timer.publish(every: 2, on: .main, in: .default)
.autoconnect()
.scan(false) { shouldDisplay, _ in
!shouldDisplay
}
.assign(to: \.value, on: shouldDisplaySubject)
.store(in: &cancellables)
}
}
You can use Timer.Publisher
like this:
toggleShouldDisplay = Timer.publisher(every: 2, on: .main, in: .default)
.autoconnect()
.sink {
self.shouldDisplay = !self.shouldDisplay
self.didChange.send(())
}
autconnect()
lets the Timer
start as soon as you subscribe using sink(_:)
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With