Cache URLResponses in Swift

We don’t want to preload every ViewModel!

Photo by Abel Y Costa

Difficulty: Beginner | Easy | Normal | Challenging
This article has been developed using Xcode 12, and Swift 5.3

Prerequisites:

* You will be expected to make a Single View Swift Application
* This code is built on my network manager, which you can download and use for free
* This involves subscripts that I’m covered in Create your own subscript
* This code uses Singletons

Terminology

Cache: a collection of items of the same type stored

Alamofire has a cache. Surely I can make a simlar feature for my own Network manager? (Spoiler: Yes, yes I can).

This allows use of dependency injection and provides us with a suitable way of testing our code. That is great!

Note that I’ve left print logging in the code that I’ve checked in, this is so we can see when data is stored and used from the cache by looking at the console. You wouldn’t want to do that in production code (so please don’t!)

Coding to an interface

In order to code to an interface you will need to use a protocol which the classes we create will conform to.

That protocol can be the following:

Now the reason for doing this is to create a mock that we can later swap out during tests — for my rather basic tests I’m not concerted about the subscript returning Data, for more complex tests this would need to be filled in.

speaking of tests, we can think of creating those to test whether the data can be restored from the cache, and this may be something like the following:

If we get the data from the cache or from the Network the code shouldn’t care. I’ve produced two different tests to demonstrate this:

So in the first test the data comes from the cache — and we check that the network manager returns that data (it does), in the second test the data comes from the network, and once again all is fine (which is great!

The altered Network Manager

The heart of this code is the following Network Manager:

Now when this is called from the code, I’d say it calls it as normal from my network manager code, which is something like the following:

Which of course uses a force-unwrap which you shouldn’t do in production code but then you can deal with the response as you might well usually do.

The whole code is in the repo, which should answer the many implementation details that you would like to confirm with me.

Conclusion

The approach taken loosely follows MVVM and I’ve whacked a few tests in there too. I hope this is of use to those reading.

Swapping out implementation details using dependency injection is really important

In any case, have a nice day.

If you’ve any questions, comments or suggestions please hit me up on Twitter

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store