Hey there! Excellent question.
I want to start off with the fact that, we unfortunately as authors can’t cover 100% of the information in a single tutorial, but this is a great piece to talk about, so let me expand a bit, and sorry in advance for the lengthy explanation but it’s great information to know
Basically, if our ViewModel wouldn’t do anything that works with any specific scheduler (meaning time-based operations: timer, interval, retry, etc.) - you usually won’t even need to inject a scheduler, but in the Metronome’s case you’ll notice we’re injecting the scheduler since we’re using Observable.interval to calculate our “beats”.
OK, great, so far so good.
Now, what happens if instead of Observable.interval(_:scheduler:)
, you would use Driver.interval(_:)
?
Drivers don’t accept a Scheduler, since they always execute on MainScheduler.instance
.
So, actually that’s not entirely true. Driver
is a SharingStrategy
, and you’ll see it’s getting its scheduler from something called SharingScheduler.make()
.
So, what is this SharingScheduler.make()
? By default, it just returns MainScheduler.instance
, which is why all Driver
schedule events on that scheduler by default. So, since we can’t inject it, how can we “mock” that SharingScheduler’s scheduler?
That’s exactly what SharingScheduler.mock
is for!
When you use SharingScheduler.mock(scheduler: testScheduler) { ... commands ... }
- what you’re saying is, whenever you would use a Sharing Strategy, instead of using the default scheduler, use my injected scheduler. So in a way, it’s the same as injecting your scheduler into your View Model, but across all SharingStrategies (Driver/Signal) in the scope of that call.
Sorry if that was a bit technical, hope it helps / made sense to you!
Shai.