This content originally appeared on Level Up Coding - Medium and was authored by Liana Haque
Store images, and other media files to memory or storage with URLCache — an alternative to NSCache.
Image Caching & Persistence with URLCache
Surprisingly, there’s not a lot of content regarding URLCache and its neat use-cases, so I wrote a short piece on it and its ability to simultaneously handle network calls and caching binary objects.
I will be showing you how I boosted my image loading speed by 4x and dropped the number of network calls my app was creating.
I also got a little carried away and wrote a little bit about distinguishing in-memory vs. on-disk storage in this article for people who may be unfamiliar with the topic.
However, you may not need to worry too much as URLCache handles caching to both these locations!
By the end of this article you:
- Will learn how to use URLCache to cache and persist binary objects (such as images, audio files, etc.) from network calls.
- (Optionally) Can gain a high level understanding of memory vs. storage and their respective roles in mobile development.
I was trying to cache background images from an API so I don’t have to download them every time my app started. If the app was re-opened and if the image was still relevant to conditions written in my app then it would be loaded from the cache. For example, in a weather app I’m writing, if the image no longer matched weather conditions of a location, it would have to change.
Building this feature led me down a road of (mistakenly, but happily) learning NSCache, learning about memory, storage, RAM and HDDs, and then finding my solution with URLCache (and then writing this article after realizing how scarce writing is about it).
Fun Misadventures with NSCache
I’m sure most of us have touched upon NSCache at some point or another. It’s a dictionary-esque collection structure that stores key-value pairs to arrange data. It boots out data once resources become limited however. You can tell this was definitely not the most ideal tool for my uses.
Read more about NSCache here.
While its use may seem like it would be flimsy or limited, it’s actually fantastic for handling the bread and butter of iOS apps — UITableViews and UICollectionViews.
NSCache is ideal for UITableViews and UICollectionViews that need to quickly cache and reuse cell content. The data stored for those cells are kept by NSCache, which stores data in-memory, so it’s readily accessible by RAM. This comes in handy if your user is scrolling up and down and up again in your app. You can read more about NSCache and its use cases in image caching from this here.
This is ideal for speed, but it lacks in persistence as contents within RAM terminate upon turning off a device or closing an app.
I need something that offers me on-disk caching so that I can persist these images.
In-Memory vs. On-Disk
Apps are stored within random-access-memory on your phone. Data that needs to persist, and live beyond app and phone restarts need to live in the disk space. Disk Space is also known as storage and hard-drive.
The pros of drives are that they can store more data compared to memory, and are ideal for large files such binary objects (images, audio files, etc). The cons are that they are much slower than RAM.
In contrast, RAM are faster than drives but can store less in comparison.
RAM would be ideal to store assets such as images in a UICollectionView or UITableView so that they can be reused without having to make several dozen network calls in the app.
The drive would be best to store images beyond a single user session. It’s good for use cases such as a user saving an image to a gallery, or saving a voice memo.
This should be enough context to understand the problem at hand, and nifty to know since URLCache caches to both!
CODE!
The guts of this tutorial project lies in the ImageRepository. The core functionality of the ImageRepository is declared by the protocols below. Protocols are a great way of laying the primary function and foundation down for a class.
The main functions of the ImageRepository are described here:
The ImageRepository is responsible for handling image related actions.
If ‘Promise’ looks unfamiliar — don’t worry. It’s just an async library I’m using here. I highly recommend you take a look at PromiseKit if you want something middle-weight compared to Combine or Rx. It’s well maintained, and reliable.
Here’s the ImageRepository in its entirety.
Let me break this down bit by bit.
getImage will determine whether or not we should get the image from a network call or the cache.
downloadImage delivers a UIImage that must be initialized from the data we received from the dataTask.
The dataTask ensures there’s data and then stores it in the format of a CachedURLResponse . The CachedURLResponse object is stored in both memory and storage caches, and to fulfill the needs of the function, we deliver a UIImage that must be initialized from the data we received.
On line 9, we are saving the cachedData and correspond it to a url request.
loadImageFromCache primarily returns a cached url response that corresponds with the specified URL request.
We seek out the data via request and then initialize a UIImage with the data retrieved.
Warnings When Caching to Drive
Apple does warn that URLCache may purge your data if your device is running low on storage — same as NSCache.
Also, be wary of saving sensitive information (i.e. user information, addresses, etc.) onto disk as it is insecure.
I am not knowledgable on encryption (yet) so I will not be covering it in the scope of this article.
Bonus! Speed check between memory and storage.
In the full tutorial project, the ViewController holds a bit of code that prints out the number of milliseconds it takes for the downloadImage and loadImageFromCache to complete.
When I ran 10 tests comparing the averages, I found that retrieving data from memory was 4x faster than retrieving it from storage.
We all knew that would be the case but I thought it would be fun to see.
Average of Download Speeds: 364 Milliseconds
Average of Cache Speeds: 91 Milliseconds
4x Faster on Average.
Here is a link to the full project: https://github.com/baruma/CacheImageToDisk-Tutorial
Conclusion!
I hope this article was informative, or at least expands upon URLCache a bit more for more folks unfamiliar with it!
Content I used in my learning:
- https://medium.com/@master13sust/to-nscache-or-not-to-nscache-what-is-the-urlcache-35a0c3b02598
- https://medium.com/flawless-app-stories/reusable-image-cache-in-swift-9b90eb338e8d
- https://medium.com/swift2go/swiftbits-caching-images-9de11d034924
- https://www.backblaze.com/blog/whats-diff-ram-vs-storage/
Image Caching with URLCache was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.
This content originally appeared on Level Up Coding - Medium and was authored by Liana Haque
Liana Haque | Sciencx (2021-08-19T14:11:12+00:00) Image Caching with URLCache. Retrieved from https://www.scien.cx/2021/08/19/image-caching-with-urlcache/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.