Reputation: 582
I am trying to create a scheduler to consume some data.
The scheduler will have to be able to:
I have modelled the manual consumption with a MutableProperty
let consume = MutableProperty<Void>()
and I am trying to model the automatic consumption with a SignalProducer
let timer = SignalProducer<Void, NoError>
I can get the first time that I need to consume that data by combining the latest values of these two producers like
SignalProducer.combineLatest(consume.producer, timer)
.take(first: 1)
.map() { _ in return () }
That way whichever comes first, a manual consumption or an automatic one the producer will send a value.
I can't figure out how I will be able to do this perpetually.
Can someone help?
Upvotes: 3
Views: 3253
Reputation: 99
You can wrap timer into SignalProducer
func timerProducer() -> SignalProducer<Void, Never> {
return SignalProducer<Void, Never> { observer, disposable in
let timer = Timer(timeInterval: 10, repeats: true) { timer in
if disposable.hasEnded {
timer.invalidate()
} else {
observer.send(value: ())
}
}
RunLoop.main.add(timer, forMode: .common)
}
}
Note: If you starting this producer from NON-main thread, you need add it to RunLoop. Otherwise it will not get triggered.
Upvotes: 0
Reputation: 2371
You can start a timer using the global timer functions defined in ReactiveSwift
public func timer(interval: TimeInterval, on scheduler: DateSchedulerProtocol) -> SignalProducer<Date, NoError>
To combine the timer with the consume property:
let interval = 10.0
let timerSignal: SignalProducer<Date, NoError> = timer(interval: interval, on: QueueScheduler.main)
let consume = MutableProperty<Void>()
timerSignal.combineLatest(with: consume.producer).startWithValues { (date, v) in
print("triggered at time: \(date)")
}
This way you can trigger the print block manually by setting the value
property on consume, or by waiting for the timer event.
Upvotes: 5