gkaimakas
gkaimakas

Reputation: 582

ReactiveSwift: How to write a Task Scheduler

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

Answers (2)

Yehor Chernenko
Yehor Chernenko

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

marosoaie
marosoaie

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

Related Questions