{"id":826,"url":"https://github.com/zolomatok/Johnny","last_synced_at":"2025-07-30T19:32:28.456Z","repository":{"id":56916933,"uuid":"62321374","full_name":"zolomatok/Johnny","owner":"zolomatok","description":"Melodic Caching for Swift","archived":false,"fork":false,"pushed_at":"2019-09-10T08:14:11.000Z","size":335,"stargazers_count":37,"open_issues_count":0,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-26T08:18:24.753Z","etag":null,"topics":["caching","generic","ios","macos","tvos","watchos"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zolomatok.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-06-30T15:22:35.000Z","updated_at":"2024-06-28T08:39:35.000Z","dependencies_parsed_at":"2022-08-21T03:50:43.672Z","dependency_job_id":null,"html_url":"https://github.com/zolomatok/Johnny","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/zolomatok/Johnny","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zolomatok%2FJohnny","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zolomatok%2FJohnny/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zolomatok%2FJohnny/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zolomatok%2FJohnny/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zolomatok","download_url":"https://codeload.github.com/zolomatok/Johnny/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zolomatok%2FJohnny/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267928985,"owners_count":24167431,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-30T02:00:09.044Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["caching","generic","ios","macos","tvos","watchos"],"created_at":"2024-01-05T20:15:32.258Z","updated_at":"2025-07-30T19:32:28.107Z","avatar_url":"https://github.com/zolomatok.png","language":"Swift","funding_links":[],"categories":["Cache"],"sub_categories":["Other free courses","Getting Started"],"readme":"![Logo](/Johnny/johnny-logo.png?raw=true)\n\n![platform](https://cdn.rawgit.com/zolomatok/Johnny/master/platform.svg)\n![license](https://cdn.rawgit.com/zolomatok/Johnny/master/license.svg)\n\nJohnny is a generic caching library written for Swift 4.\n\n## Features\n**Johnny can cache any model object that conforms to the `Cachable` protocol.**\n\n- [x] Out-of-the-box support:\n  - String, Bool, Int, UInt, Int64, UInt64, Float, Double\n  - URL, Data, Date\n  - UIImage, UIColor **by wrapping them in an Image or Color wrapper class respectively**\n  - Arrays, Dictionaries and Sets of the above\n- [x] Multiplatform, supporting iOS, macOS, tvOS \u0026 watchOS\n- [x] First-level memory cache using `NSCache`\n- [x] Second-level LRU disk cache\n- [x] Disk access in background thread (always when saving, optionally when fetching)\n- [x] Syncronous \u0026 Asynchronous API support\n- [x] Automatic cache eviction on memory warnings \u0026 disk capacity reached\n- [x] Unit tested\n- [x] Concise, well-structured code to encourage contributions\n\nExtra ❤️ for images:\n- [x] `func setImageWithURL` extension on UIImageView, UIButton \u0026 NSImageView, optimized for cell reuse\n\n## Usage\n\n### Caching ###\n```swift\nJohnny.cache(user, key: \"LocalUser\")\n\nlet imgage = UIImage(named: \"awesomeness\")\nJohnny.cache(Image(image), key: \"Image\") // Caching a UIImage. UIColor objects must be wrapped in the Color wrapper class the same way.\n\n// 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:\nJohnny.cache(Date(), key: \"FirstStart\", library: true)\n```\n\n### Pulling ###\n\n```swift\n// The type of the retrived value must be explicitly stated for the compiler.\nlet date: Date? = Johnny.pull(\"FirstStart\")\n\n// If you know you are retrieving a large object (\u003e 1.5 MB) you can do it asynchronously\nJohnny.pull(\"4KImage\") { (image: Image?) in\n    let img = image.uiImage()\n}\n```\n\n### Removing ###\n```swift\nJohnny.remove(\"LocalUser\")\n```\n\n\n## Examples\n\n### Collections ###\n\nYou can cache any collection of items conforming to the Storable protocol (most standard library data types already do)\n\n```swift\nlet array: [String] = [\"Folsom\", \"Prison\", \"Blues\"]\nlet stringSet: Set\u003cString\u003e = [\"I've\", \"been\", \"everywhere\"]\n// In case of dictionaries, the value must explicitly conform to Storable (so [String: AnyObject] does not work, while [String: Double] does)\nlet dictionary: [String: String] = [\"first\": \"Solitary\", \"second\": \"man\"]\n\nJohnny.cache(array, key: \"folsom\")\nJohnny.cache(stringSet, key: \"everywhere\")\nJohnny.cache(dictionary, key: \"solitary\")\n```\n\n### Custom types ###\n\nDue to current Swift limitations, since the Storable protocol has an `associatedType`, conformance must be added through an extension.\n`class User: Storable` will not work.\n\n\n```swift\nstruct User {\n    \n    enum Badassery: String { case Total }\n    \n    var name: String?\n    var uid: Int\n    var badassery: Badassery\n}\n\n\nextension User: Storable {\ntypealias Result = User\n\nstatic func fromData(data: NSData) -\u003e User.Result? {\n    let dict = try! NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions()) as! [NSObject: AnyObject]\n\n    let user = User()\n    user.uid = dict[\"identification\"] as! Int\n    user.name = dict[\"name\"] as? String\n    user.badassery = Badassery(rawValue: dict[\"badassery\"] as! String)!\n    return user\n}\n\nfunc toData() -\u003e NSData {\n    let json = [\"identification\": uid, \"name\": name, \"badassery\": badassery.rawValue]\n    return try! NSJSONSerialization.dataWithJSONObject(json, options: NSJSONWritingOptions())\n    }\n}\n```\n\n**Using it with Johnny:**\n\n\n```swift\nlet lily = User(name: \"Lily\", uid: 84823682, badassery: .Total)\nJohnny.cache(lily, key: \"Lily\")\n\nlet cachedLily: User = Johnny.pull(\"Lily\")\n```\n\n## Requirements\n- iOS 8.0+\n- macOS 10.10+\n- tvOS 9.0+\n- watchOS 2.0+\n- Swift 4.0\n\n## Install\n\n**CocoaPods**\n\n```\npod 'Johnny'\n```\n\n**Carthage**\n\n```\ngithub \"zolomatok/Johnny\"\n```\n\n**Manual**\n- Clone the project\n- Select the scheme (platform) and build\n- Drag Johnny.framework to your project\n- 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.\n\n\n## Attribution\nI'd like to thank the creators of [Pantry](https://github.com/nickoneill/Pantry) and [Haneke](https://github.com/Haneke/HanekeSwift) as those projects provided much of the inspiration and some code. Johnny was dreamed up to be the best of both worlds.\n\n## License\nJohnny is released under the MIT license. See LICENSE for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzolomatok%2FJohnny","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzolomatok%2FJohnny","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzolomatok%2FJohnny/lists"}