- Description
- Key features
- Usage
- Optional bonuses
- What about images?
- Installation
- Author
- Contributing
- License
- Generic
Cachable
protocol to be able to cache any type you want. CacheAware
andStorageAware
protocols to implement different kinds of key-value cache storages. The basic interface includes methods to add, get and remove objects by key.Cache
class to create a type safe cache storage by a given name for a specifiedCachable
-compliant type.HybridCache
class that works with every kind ofCachable
-compliant types.- Flexible
Config
struct which is used in the initialization ofCache
andHybridCache
classes, based on the concept of having front- and back- caches. A request to a front cache should be less time and memory consuming (NSCache
is used by default here). The difference between front and back caching is that back caching is used for content that outlives the application life-cycle. See it more like a convenient way to store user information that should persist across application launches. Disk cache is the most reliable choice here. StorageFactory
- a place to register and retrieve your cache storage by type.- Possibility to set expiry date + automatic cleanup of expired objects.
- Basic memory and disk cache functionality.
- Scalability, you are free to add as many cache storages as you want (if default implementations of memory and disk caches don't fit your purpose for some reason).
NSData
encoding and decoding required byCachable
protocol are implemented forUIImage
,String
,JSON
andNSData
.- iOS and OSX support.
HybridCache
supports storing all kinds of objects, as long as they conform to
the Cachable
protocol. It's two layered cache (with front and back storages),
as well as Cache
.
Initialization with default configuration
let cache = HybridCache(name: "Mix")
Initialization with custom configuration
let config = Config(
// Your front cache type
frontKind: .Memory,
// Your back cache type
backKind: .Disk,
// Expiry date that will be applied by default for every added object
// if it's not overridden in the add(key: object: expiry: completion:) method
expiry: .Date(NSDate().dateByAddingTimeInterval(100000)),
// Maximum size of your cache storage
maxSize: 10000)
let cache = HybridCache(name: "Custom", config: config)
Basic operations
let cache = HybridCache(name: "Mix")
// String
cache.add("string", object: "This is a string")
cache.object("string") { (string: String?) in
print(string) // Prints "This is a string"
}
// JSON
cache.add("jsonDictionary", object: JSON.Dictionary(["key": "value"]))
cache.object("jsonDictionary") { (json: JSON?) in
print(json?.object)
}
// UIImage
cache.add("image", object: UIImage(named: "image.png"))
cache.object("image") { (image: UIImage?) in
// Use your image
}
// NSData
cache.add("data", object: data)
cache.object("data") { (data: NSData?) in
// Use your NSData object
}
// Remove an object from the cache
cache.remove("data")
// Clean the cache
cache.clear()
Initialization with default or custom configuration, basic operations and
working with expiry dates are done exactly in the same way as in HybridCache
.
Basic operations
// Create an image cache, so it's possible to add only UIImage objects
let cache = Cache<UIImage>(name: "ImageCache")
// Add objects to the cache
cache.add("image", object: UIImage(named: "image.png"))
// Fetch objects from the cache
cache.object("image") { (image: UIImage?) in
// Use your image
}
// Remove an object from the cache
cache.remove("image")
// Clean the cache
cache.clear()
Cache
was born to be async, but if for some reason you need to perform cache
operations synchronously, there is a helper for that.
let cache = HybridCache(name: "Mix")
let syncCache = SyncHybridCache(cache)
// Add UIImage to cache synchronously
syncCache.add("image", object: UIImage(named: "image.png"))
// Retrieve image from cache synchronously
let image: UIImage? = syncCache.object("image")
// Remove an object from the cache
syncCache.remove("image")
// Clean the cache
syncCache.clear()
SyncCache
works exactly in the same way as SyncHybridCache
, the only
difference is that it's a wrapper around a type safe cache.
let cache = Cache<UIImage>(name: "ImageCache")
let syncCache = SyncCache(cache)
syncCache.add("image", object: UIImage(named: "image.png"))
let image = syncCache.object("image")
syncCache.remove("image")
syncCache.clear()
// Default cache expiry date will be applied to the item
cache.add("string", object: "This is a string")
// A provided expiry date will be applied to the item
cache.add("string", object: "This is a string",
expiry: .Date(NSDate().dateByAddingTimeInterval(100000)))
Encode and decode methods should be implemented if a type conforms to Cachable
protocol.
class User: Cachable {
typealias CacheType = User
static func decode(data: NSData) -> CacheType? {
var object: User?
// Decode your object from data
return object
}
func encode() -> NSData? {
var data: NSData?
// Encode your object to data
return data
}
}
JSON is a helper enum that could be Array([AnyObject])
or Dictionary([String : AnyObject])
.
Then you could cache JSON
objects using the same API methods:
cache.add("jsonDictionary", object: JSON.Dictionary(["key": "value"]))
cache.object("jsonDictionary") { (json: JSON?) in
print(json?.object)
}
cache.add("jsonArray", object: JSON.Array([
["key1": "value1"],
["key2": "value2"]
]))
cache.object("jsonArray") { (json: JSON?) in
print(json?.object)
}
You could use this NSData
encoding and decoding implementation for any kind
of objects, but do it on your own risk. With this approach decoding
will not work if the NSData
length doesn't match the type size. This can commonly
happen if you try to read the data after updates in the type's structure, so
there is a different-sized version of the same type. Also note that sizeof()
and sizeofValue()
may return different values on different devices.
do {
object = try DefaultCacheConverter<User>().decode(data)
} catch {}
do {
data = try DefaultCacheConverter<User>().encode(self)
} catch {}
As being said before, Cache
works with any kind of Cachable
types, with no
preferences and extra care about specific ones. But don't be desperate, we have
something nice for you. It's called Imaginary
and uses Cache
under the hood to make you life easier when it comes to working
with remote images.
Cache is available through CocoaPods. To install it, simply add the following line to your Podfile:
pod 'Cache'
Cache is also available through Carthage. To install just write into your Cartfile:
github "hyperoslo/Cache"
Hyper made this with ❤️. If you’re using this library we probably want to hire you! Send us an email at ios@hyper.no.
We would love you to contribute to Cache, check the CONTRIBUTING file for more info.
Cache is available under the MIT license. See the LICENSE file for more info.