A lightweight caching and data retrieval library for iOS which aims to be as non-intrusive as possible. To see example usage of EZCache check out the sample project repository.
The original aim of the project was to understand when and where to use generics in software engineering. Swift, being a language that favors strongly typed software patterns, was perfect for this. Further understanding was achieved through the implementation of generic protocols with associated types and inferred generic typing with multiple layers of abstraction for different types of caching.
Implement Cacheable
on the struct
or class
you want to cache. If your object conforms to Codable
it's really simple to get started.
extension YourData: Cacheable { }
Instantiate a DataFetcher
on an object that won't be deallocated during use such as a UIViewController
or a view model layer. If the DataFetcher
or its parent is deallocated the underlying Cache
will be invalidated and emptied.
let dataFetcher = DataFetcher<YourData>()
Provide a URL
with some data that conforms to your data type whether it be image data or JSON. If this operation has previously been successful for the specified URL
during the lifecycle of the DataFetcher
then it will retrieve it from the cache. If the DataFetcher
is new or the app was terminated then it will attempt to retrieve it from local storage instead.
self.dataFetcher.fetch(from: URL("http://www.myurl.com/data")!) { (result) in
switch result {
case .success(let yourData):
// Do something with your data
break
case .failure(let error):
break
}
}
...and that's pretty much it! There are a few other things you can customise and fine tune using Cacheable
which you'll need to do if you want to decode more elaborate data such as an image, PDF or another file format. Here's an example of a more precise implementation of Cacheable
from the CacheableImage
struct:
extension CacheableImage: Cacheable {
public static var subdirectoryName: String { return "images" }
public static var fileExtension: String { return ".png" }
public static var storagePolicy: StoragePolicy { return .allowStale }
public static func decode(from data: Data) throws -> CacheableImage {
guard let image = UIImage(data: data) else { throw CachingError.decodingFailed }
return CacheableImage(image)
}
public func toData() throws -> Data? {
return self.rawValue.pngData()
}
}
- Provide real error handling
- Introduce
StoragePolicy
to allow state data refreshing or ignorance - Streamline
Cacheable
implementation by providing default values and functions - Change any remaining synchronous calls into asynchronous or provide both
- Allow
DataFetcher
to be constructed with a passedCache
instance, but default to a shared singleton instance if none is provided - Introduce
UIImageView
helper or subclass for making network calls even simpler - Tidy up code
- Provide useful comments