Latest 2.0
License MIT
Platforms osx 10.10, ios 8.0, tvos 9.0, watchos 2.0, requires ARC



Johnny is a generic caching library written in Swift 3.


Johnny can cache any model object that conforms to the Storable protocol.

Note, that since the protocol uses a static constructor function instead of an initializer, you can extend any class and make them conform to Storable, even if you don’t have access to its source (for example, Apple’s classes)

public protocol Storable {
    associatedtype Result
    static func fromData(data: Data) -> Result?
    func toData() -> Data
  • [x] Out-of-the-box support:
    • String, Bool, Int, UInt, Int64, UInt64, Float, Double
    • URL, Data, Date
    • UIImage, UIColor
    • Arrays, Dictionaries and Sets of the above
  • [x] Multiplatform, supporting iOS, macOS, tvOS & watchOS
  • [x] First-level memory cache using NSCache
  • [x] Second-level LRU disk cache
  • [x] Disk access in background thread (always when saving, optionally when fetching)
  • [x] Syncronous & Asynchronous API support
  • [x] Automatic cache eviction on memory warnings & disk capacity reached
  • [x] Unit tested
  • [x] Concise, well-structured code to encourage contributions

Extra ❤️ for images:

  • [x] func setImageWithURL extension on UIImageView, UIButton & NSImageView, optimized for cell reuse



Johnny.cache(user, key: "LocalUser")

// 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)


// 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: UIImage?) in






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.

class User {

    enum Badassery: String { case Total }

    var name: String? = "Johnny"
    var uid: Int = 84823682
    var badassery = Badassery.Total

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 = dict["name"] as? String
    user.badassery = Badassery(rawValue: dict["badassery"] as! String)!
    return user

func toData() -> NSData {
    let json = ["identification": uid, "name": name, "badasery": badassery.rawValue]
    return try! NSJSONSerialization.dataWithJSONObject(json, options: NSJSONWritingOptions())

Using it with Johnny:

let johnny: User = User()
Johnny.cache(johnny, key: "John")
let cachedJohn: User = Johnny.pull("John")


  • iOS 8.0+
  • macOS 10.10+
  • tvOS 9.0+
  • watchOS 2.0+
  • Swift 3.0+



pod 'Johnny'


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.


Johnny is released under the MIT license. See LICENSE for details.

Latest podspec

    "name": "Johnny",
    "version": "2.0",
    "summary": "Melodic Caching in Swift",
    "homepage": "",
    "license": {
        "type": "MIT"
    "authors": {
        "Zoltu00e1n Matu00f3k": "[email protected]"
    "source": {
        "git": "",
        "tag": "2.0"
    "requires_arc": true,
    "module_name": "Johnny",
    "platforms": {
        "osx": "10.10",
        "ios": "8.0",
        "tvos": "9.0",
        "watchos": "2.0"
    "osx": {
        "source_files": [
        "frameworks": [
    "ios": {
        "source_files": [
        "frameworks": [
    "tvos": {
        "source_files": [
        "frameworks": [
    "watchos": {
        "source_files": [
    "pushed_with_swift_version": "3.0"

Pin It on Pinterest

Share This