SwiftyCache is a dynamic and auto-managed cache written in Swift. Unlike a simple cache system, it allows you to keep some data even in different executions. Guaranteeing persistence, when desired, without increasing the time required to save or recover data.
- Easy to use: it uses a key-value syntax like any dictionary or some NoSql databases.
- Shared: it is based on a single instance shared by the whole app. A data saved in one point can be easily accessed in another.
- Heterogeneous: it allows you to store objects of a different types in the same space. Native types are already compatible.
- Dynamic: During its life it changes its size continuously according to the actual content. Re-compacting when possible and deleting expired data. It is also possible to insert a limit to the maximum reachable size.
- Auto-managed: you don't have to think about how, when and where to store a data. SwiftyCache manages everything for you.
- Fast: it guarantees the same performances of NSCache despite offering more functionalities.
- Safe: it is thread safe, so you can access it from any thread without worrying about managing threads.
- Lightweight: it efficiently uses memory, disk space, and battery life. In critical situations it automatically chooses if and which data to remove to improve performance.
Installation
You can use Swift Package Manager to add SwiftyPackage to your project.
Add Package Dependency
In Xcode, select File > Add Packages...
Specify the Repository
Copy and paste the following into the search/input box.
https://github.com/antonio-war/SwiftyCache
Specify options
Use Up to Next Major Version as dependency rule and enter the current SwiftyCache version. Then click Add Package.
Getting Started
Keys
SwiftyCache allows you to use any type conforming to the SwiftyCacheKey protocol as a key. Most native types already conform to this protocol, so you can use Int, String, URL etc. without having to do anything.
If you want to use a custom type as cache key, just make it compliant with the protocol.
struct Person: SwiftyCacheKey {
let name: String
let surname: String
}
Values
SwiftyCache allows you to use any type conforming to the SwiftyCacheValue protocol as a value. The reasoning is the same applied to the keys.
struct Person: SwiftyCacheValue {
let name: String
let surname: String
}
Store an object
To store an object in the cache you need to use the set method, which provides some possible configurations.
Default storage
By default SwiftyCache stores data only in memory and for an indefinite time. In fact, they will be deleted only if explicitly requested by the user or in critical cases in which the operating system needs to free up the memory. However, this is a non-persistent storage so the data is lost when the user closes the App.
The following example downloads data from the web and saves it in the cache to retrieve them later.
let url = URL(string: "https://cdn.cocoacasts.com/cc00ceb0c6bff0d536f25454d50223875d5c79f1/above-the-clouds.jpg")!
if let data = try? Data(contentsOf: url) {
SwiftyCache.shared.set(value: data, for: url)
}
Storage with expiration
Sometimes the data downloaded from the web has a limited duration, after which it becomes invalid. Therefore SwiftyCache provides the possibility of associating an expiration with this data so that it is automatically deleted when necessary.
To do this SwiftyCache provides a utility called SwiftyCacheDuration. It provides a quick and easy way to specify seconds, minutes, hours and even days of validity.
The following example considers the data to be valid for only 30 seconds.
SwiftyCache.shared.set(value: data, for: url, duration: .seconds(quantity: 30))
Persistent storage
As already mentioned, SwiftyCache allows you to store data persistently, in order to find it cached even after restarting the App.
To ensure the persistent cache works, it is necessary to specify among the schema environment variables: SWIFT_DETERMINISTIC_HASHING = 1
Obviously, an expiration date can also be associated with this type of storage, as seen previously.
SwiftyCache.shared.set(value: data, for: url, duration: .days(quantity: 1), persisted: true)
Retrieve an object
SwiftyCache allows you to retrieve objects using the get method. It requires you to specify the type of data to be recovered. The method returns 'nil' if the data does not exist or has expired.
If you want to recover the previously saved data, which were of the Data type, the call will be as follows.
let value = SwiftyCache.shared.get(key: url, as: Data.self)
Delete objects
As for the deletion of objects, SwiftyCache provides two methods: one for single deletion and one for deleting all data. In the first case it is obviously necessary to specify the key of the data to be deleted.
SwiftyCache.shared.remove(key: url)
SwiftyCache.shared.removeAll()
Set a maximum size
As previously mentioned, SwiftyCache allows you to set a maximum size in order to prevent the data to be managed from becoming too heavy. All you have to do is call the setMaximumSize method, the memory will then be managed automatically by SwiftyCache which will remove the oldest and / or least used data.
To do this SwiftyCache provides a utility called SwiftyCacheSize. It provides a quick and easy way to specify bytes, megabytes and gigabytes.
SwiftyCache.shared.setMaximumSize(size: .megabytes(quantity: 500))
Image Caching
Images are even easier to cache than other objects. In fact, everything will be possible through a constructor that encapsulates and manages all the calls relating to the methods seen above. If your goal is to download images via their URL and cache them, SwiftyCache is for you.
let url = URL(string: "https://cdn.cocoacasts.com/cc00ceb0c6bff0d536f25454d50223875d5c79f1/above-the-clouds.jpg")!
let image = UIImage(url: url)
In the basic form the constructor caches the image in memory and does not set any duration, so it is always valid within the same session. Whenever the App tries to instantiate an image with the same URL, the cached version will be taken.
Duration
As seen previously SwiftyCache allows you to set a duration for each object, so that after a certain period of time it is no longer considered valid. This possibility has also been guaranteed for images.
let image = UIImage(url: url, duration: .seconds(quantity: 30))
Persistence
A very useful function is to persistently cachare the images, in order to save time even in subsequent openings of the App.
let image = UIImage(url: url, persisted: true)
Using the cached version of the image rather than re-downloading it turns out to be about 10 times faster.
Update
In some cases you may want to re-download the image by discarding the saved version, this is possible through the force update option.
let image = UIImage(url: url, forceUpdate: true)
This does not bother to check if a version already exists in memory or if it is valid. It will directly download the image and save it by overwriting the old one.
License
SwiftyCache is published under the Apache 2.0 license.