Swift 5.7 was released a few months ago, and with it came a new tool for dealing with time-based asynchrony, but it has mostly flown under the radar so far. I’m talking about the Clock
protocol, which encapsulates the idea of suspending for an amount of time in an asynchronous context.
This concept is similar to schedulers that are native to the Combine framework. Schedulers encapsulates the idea of how to schedule work at a future date, or even repeatedly on an interval. Schedulers pair well with reactive programming frameworks such as Combine because they can not only express time-based asynchrony, but can also describe the execution context of where to perform work or deliver values, such as on a particular dispatch queue, operation queue or run loop.
But clocks operate in Swift’s new structured concurrency model, and so they can be a lot simpler than schedulers. They don’t need to describe how or where they are going to perform work. They can simply use a surrounding asynchronous context to suspend for an amount of time, and then once that time passes it will allow execution to continue flowing in its task. No need to think about threads or queues.
So, it’s great that clocks are simpler than schedulers, and of course it would be great if we could slowly replace any usages of schedulers with clocks in order to remove yet another dependency on the Combine framework. But, if we’re not careful, we will accidentally introduce time-based asynchrony into our features that is completely uncontrollable, making it harder to iterate on our features and harder, if not impossible, to test our features.
So, this episode we are going to explore the new Clock
protocol to see why it’s so special, and then see what needs to be done so that we can take control of time rather than having it control us.