🎉 End-of-year Sale! Save 25% when you subscribe today.

Clocks: Controlling Time

Episode #210 • Oct 24, 2022 • Subscriber-Only

With “immediate” and “unimplemented” conformances of the Clock protocol under our belt, let’s build something more complicated: a “test” clock that can tell time when and how to flow. We’ll explore why we’d ever need such a thing and what it unlocks.

Previous episode
Clocks: Controlling Time
Next episode
Locked

Unlock This Episode

Our Free plan includes 1 subscriber-only episode of your choice, plus weekly updates from our newsletter.

Sign in with GitHub

Introduction

So, this is pretty amazing. After diving deep into the Clock protocol so that we could understand what core concept it represents, and seeing how it differs from Combine schedulers, we showed how to make use of clocks in our features. There were a number of false starts to do that, first needing to wrap our minds around clock existentials and primary associated types and then coming to grips with some missing APIs in the standard library, but once we got out of the weeds we had the ability to swap clocks in and out of our feature code. We could use a continuous clock in the feature when running on a device, but sub out for a more controllable clock in tests and SwiftUI previews.

That led us to the creation of the “immediate” clock and the “unimplemented” clock. Both are powerful, and allow you to make your tests stronger and make it so that you don’t have to literally wait for time to pass in order to see how your feature behaves.

But there’s one more kind of clock that we want to have for our tests, and it’s even more powerful than any of the other clocks we have discussed. While the immediate clock allows us to squash all of time into a single instant, that isn’t always what we want. Sometimes we want to actually control the flow of time in our feature so that we can see how multiple time-based asynchronous tasks interleave their execution, or so that we can wiggle ourselves in between time-based tasks to see what is happening between events.

This is something we explored quite a bit in our series of episodes on Combine schedulers. When writing highly reactive code that needs to leverage time-based operators, such as delays, debounces and throttles, it becomes very important to have a scheduler for which you can explicitly control the flow of time.

So, let’s see why exactly we want this tool, and what it takes to implement it.

The problem


References

Downloads

Sample code

Get started with our free plan

Our free plan includes 1 subscriber-only episode of your choice, access to 64 free episodes with transcripts and code samples, and weekly updates from our newsletter.

View plans and pricing