I created a timer via combine which emits Date
and ignores errors using this code:
let timer: AnyPublisher<Date, Never> = Timer.publish(every: 5, on: .main, in: RunLoop.Mode.common)
.autoconnect()
.map { _ in Date() }
.replaceError(with: Date())
.eraseToAnyPublisher()
(I'm sure there are better ways than mapping and replacing the error, but for this example, I wanted to keep the type simple, AnyPublisher<Date, Never>
.)
The timer fires correctly, but there is a delay between when the timer is created to when it fires the first time (i.e. it waits 5 seconds). With NSTimer, we can invoke timer.fire() to force it to fire immediately.
Is there an equivalent way to force a timer to post immediately when using Timer.publish()
?
Alternatively, is there a way to merge Just(Date())
with the above Timer.publish
so that it fires immediately and every 5 seconds, while still keeping the AnyPublisher<Date, Never>
type?
I'm sure there are better ways than mapping and replacing the error
Timer.TimerPublisher.Failure
is Never
, so you don't need any mapping because it can't fail.
Furthermore, Timer.TimerPublisher.Output
is already the current Date()
, so you don't need to map
the output either.
To emit the current date immediately on subscription, you want to combine a Deferred { Just(Date()) }
with the timer publisher. The Deferred
means the current date won't be computed until the subscription happens.
Here is one way to put it all together:
let timer = Deferred { Just(Date()) }
.append(Timer.publish(every: 5, on: .main, in: .common).autoconnect())
.eraseToAnyPublisher()