Modern SwiftUI: Dependencies & Testing, Part 1

Episode #219 • Jan 9, 2023 • Subscriber-Only

Uncontrolled dependencies can wreak havoc on a modern SwiftUI code base. Let’s explore why, and how we can begin to control them using a brand new library.

Collection
Modern SwiftUI
Modern SwiftUI: Dependencies & Testing, Part 1
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

Alright, so we have now introduced 3 pretty complex effects into our application. We are dealing with timers that can be paused while alerts are up, we’re requesting speech authorization from the user and starting up a speech recognition task in parallel with the timer, and on top of all of that we are listening to any changes made to the array of standups, debouncing them for a second, and then persisting the data. Oh, and we also load that data on launch.

Without these effects our little demo was nothing more than a “cute” toy. Sure we had some fun interactions like sheets, drill downs and alerts, but everything was implemented with just simple state mutation. There was no interaction with the outside world. These effects have added a whole new dimension of behavior to the demo and turned it into a full blown application.

But with that new behavior comes new challenges. We have opened up Pandora’s box of complexity and unknowability in our codebase. We already saw this in concrete terms where we saw we have effectively broken the “record meeting” preview due to the fact that it interacts with Apple’s Speech framework directly, which does not work in Xcode previews. And we saw that when we added persistence we destroyed our ability to open up the application or preview into a state with a bunch of standups stubbed in because now that data has to come from the disk.

And if those problems weren’t bad enough, we also don’t have any hope of writing unit tests for any of those code. The Speech framework doesn’t work at all in unit tests, and because we have a real life timer we are going to have to wait for real life time in our tests, which will slow down the tests. And because we are reading and writing to the real disk we are going to have to be careful to clean up after tests, or else that data will start to leak across tests, causing mystifying test failures.

This is what motivates us to finally consider properly controlling our dependencies on things like timers, the Speech framework, and disk access. Doing so allows us to fix all of these problems and more.

So, let’s quickly look at all the problems that crop up when dealing with uncontrolled dependencies, and then let’s fix them.

Uncontrolled dependencies


References

Downloads

Get started with our free plan

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

View plans and pricing