Awesome
Johnny is a generic caching library written for Swift 4.
Features
Johnny can cache any model object that conforms to the Cachable
protocol.
- Out-of-the-box support:
- String, Bool, Int, UInt, Int64, UInt64, Float, Double
- URL, Data, Date
- UIImage, UIColor by wrapping them in an Image or Color wrapper class respectively
- Arrays, Dictionaries and Sets of the above
- Multiplatform, supporting iOS, macOS, tvOS & watchOS
- First-level memory cache using
NSCache
- Second-level LRU disk cache
- Disk access in background thread (always when saving, optionally when fetching)
- Syncronous & Asynchronous API support
- Automatic cache eviction on memory warnings & disk capacity reached
- Unit tested
- Concise, well-structured code to encourage contributions
Extra ❤️ for images:
-
func setImageWithURL
extension on UIImageView, UIButton & NSImageView, optimized for cell reuse
Usage
Caching
Johnny.cache(user, key: "LocalUser")
let imgage = UIImage(named: "awesomeness")
Johnny.cache(Image(image), key: "Image") // Caching a UIImage. UIColor objects must be wrapped in the Color wrapper class the same way.
// You can flag a value to be stored in the Library instead of the Caches folder if you don't want it to be automatically purged:
Johnny.cache(Date(), key: "FirstStart", library: true)
Pulling
// The type of the retrived value must be explicitly stated for the compiler.
let date: Date? = Johnny.pull("FirstStart")
// If you know you are retrieving a large object (> 1.5 MB) you can do it asynchronously
Johnny.pull("4KImage") { (image: Image?) in
let img = image.uiImage()
}
Removing
Johnny.remove("LocalUser")
Examples
Collections
You can cache any collection of items conforming to the Storable protocol (most standard library data types already do)
let array: [String] = ["Folsom", "Prison", "Blues"]
let stringSet: Set<String> = ["I've", "been", "everywhere"]
// In case of dictionaries, the value must explicitly conform to Storable (so [String: AnyObject] does not work, while [String: Double] does)
let dictionary: [String: String] = ["first": "Solitary", "second": "man"]
Johnny.cache(array, key: "folsom")
Johnny.cache(stringSet, key: "everywhere")
Johnny.cache(dictionary, key: "solitary")
Custom types
Due to current Swift limitations, since the Storable protocol has an associatedType
, conformance must be added through an extension.
class User: Storable
will not work.
struct User {
enum Badassery: String { case Total }
var name: String?
var uid: Int
var badassery: Badassery
}
extension User: Storable {
typealias Result = User
static func fromData(data: NSData) -> User.Result? {
let dict = try! NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions()) as! [NSObject: AnyObject]
let user = User()
user.uid = dict["identification"] as! Int
user.name = dict["name"] as? String
user.badassery = Badassery(rawValue: dict["badassery"] as! String)!
return user
}
func toData() -> NSData {
let json = ["identification": uid, "name": name, "badassery": badassery.rawValue]
return try! NSJSONSerialization.dataWithJSONObject(json, options: NSJSONWritingOptions())
}
}
Using it with Johnny:
let lily = User(name: "Lily", uid: 84823682, badassery: .Total)
Johnny.cache(lily, key: "Lily")
let cachedLily: User = Johnny.pull("Lily")
Requirements
- iOS 8.0+
- macOS 10.10+
- tvOS 9.0+
- watchOS 2.0+
- Swift 4.0
Install
CocoaPods
pod 'Johnny'
Carthage
github "zolomatok/Johnny"
Manual
- Clone the project
- Select the scheme (platform) and build
- Drag Johnny.framework to your project
- In the project settings under your target's General tab, scroll down and add Johhny to the
Embedded Binaries
section if it's not already added.
Attribution
I'd like to thank the creators of Pantry and Haneke as those projects provided much of the inspiration and some code. Johnny was dreamed up to be the best of both worlds.
License
Johnny is released under the MIT license. See LICENSE for details.