[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-6841":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":16,"stars30d":16,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":17,"rankGlobal":10,"rankLanguage":10,"license":18,"archived":19,"fork":19,"defaultBranch":20,"hasWiki":21,"hasPages":19,"topics":22,"createdAt":10,"pushedAt":10,"updatedAt":23,"readmeContent":24,"aiSummary":25,"trendingCount":16,"starSnapshotCount":16,"syncStatus":26,"lastSyncTime":27,"discoverSource":28},6841,"HanekeSwift","Haneke\u002FHanekeSwift","Haneke","A lightweight generic cache for iOS written in Swift with extra love for images.","",null,"Swift",5165,582,148,90,0,39.3,"Apache License 2.0",false,"master",true,[],"2026-06-12 02:01:30","![Haneke](https:\u002F\u002Fraw.githubusercontent.com\u002FHaneke\u002FHanekeSwift\u002Fmaster\u002FAssets\u002Fgithub-header.png)\n\n[![Carthage compatible](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FCarthage-compatible-4BC51D.svg?style=flat)](https:\u002F\u002Fgithub.com\u002FCarthage\u002FCarthage)\n[![SwiftPM compatible](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FSwiftPM-compatible-brightgreen.svg)](https:\u002F\u002Fgithub.com\u002Fapple\u002Fswift-package-manager)\n[![Accio supported](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FAccio-supported-0A7CF5.svg?style=flat)](https:\u002F\u002Fgithub.com\u002FJamitLabs\u002FAccio)\n[![Platform](https:\u002F\u002Fcocoapod-badges.herokuapp.com\u002Fp\u002FHanekeSwift\u002Fbadge.png)](http:\u002F\u002Fcocoadocs.org\u002Fdocsets\u002FHanekeSwift)\n[![Build Status](https:\u002F\u002Ftravis-ci.org\u002FHaneke\u002FHanekeSwift.svg?branch=master)](https:\u002F\u002Ftravis-ci.org\u002FHaneke\u002FHanekeSwift)\n[![Join the chat at https:\u002F\u002Fgitter.im\u002FHaneke\u002FHanekeSwift](https:\u002F\u002Fbadges.gitter.im\u002FHaneke\u002FHanekeSwift.svg)](https:\u002F\u002Fgitter.im\u002FHaneke\u002FHanekeSwift?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)\n\nHaneke is a lightweight *generic* cache for iOS and tvOS written in Swift 4. It's designed to be super-simple to use. Here's how you would initalize a JSON cache and fetch objects from a url:\n\n```swift\nlet cache = Cache\u003CJSON>(name: \"github\")\nlet URL = NSURL(string: \"https:\u002F\u002Fapi.github.com\u002Fusers\u002Fhaneke\")!\n\ncache.fetch(URL: URL).onSuccess { JSON in\n    print(JSON.dictionary?[\"bio\"])\n}\n```\n\nHaneke provides a memory and LRU disk cache for `UIImage`, `NSData`, `JSON`, `String` or any other type that can be read or written as data.\n\nParticularly, Haneke excels at working with images. It includes a zero-config image cache with automatic resizing. Everything is done in background, allowing for fast, responsive scrolling. Asking Haneke to load, resize, cache and display an *appropriately sized image* is as simple as:\n\n```swift\nimageView.hnk_setImageFromURL(url)\n```\n\n_Really._\n\n## Features\n\n* Generic cache with out-of-the-box support for `UIImage`, `NSData`, `JSON` and `String`\n* First-level memory cache using `NSCache`\n* Second-level LRU disk cache using the file system\n* Asynchronous [fetching](#fetchers) of original values from network or disk\n* All disk access is performed in background\n* Thread-safe\n* Automatic cache eviction on memory warnings or disk capacity reached\n* Comprehensive unit tests\n* Extensible by defining [custom formats](#formats), supporting [additional types](#supporting-additional-types) or implementing [custom fetchers](#custom-fetchers)\n\nFor images:\n\n* Zero-config `UIImageView` and `UIButton` extensions to use the cache, optimized for `UITableView` and `UICollectionView` cell reuse\n* Background image resizing and decompression\n\n## Installation\n\nUsing [CocoaPods](http:\u002F\u002Fcocoapods.org\u002F):\n\n```ruby\nuse_frameworks!\npod 'HanekeSwift'\n```\n\nUsing [Carthage](https:\u002F\u002Fgithub.com\u002FCarthage\u002FCarthage):\n\n```\ngithub \"Haneke\u002FHanekeSwift\"\n```\n\nUsing [SwiftPM](https:\u002F\u002Fgithub.com\u002Fapple\u002Fswift-package-manager) or [Accio](https:\u002F\u002Fgithub.com\u002FJamitLabs\u002FAccio):\n\n\n```swift\n.package(url: \"https:\u002F\u002Fgithub.com\u002FHaneke\u002FHanekeSwift.git\", .upToNextMajor(from: \"0.11.2\")),\n```\n\nThen link `Haneke` in your App target like so:\n\n```swift\n.target(\n    name: \"App\",\n    dependencies: [\n        \"Haneke\",\n    ]\n),\n```\n\nManually:\n\n1. Drag `Haneke.xcodeproj` to your project in the _Project Navigator_.\n2. Select your project and then your app target. Open the _Build Phases_ panel.\n3. Expand the _Target Dependencies_ group, and add `Haneke.framework`.\n4. Click on the `+` button at the top left of the panel and select _New Copy Files Phase_. Set _Destination_ to _Frameworks_, and add `Haneke.framework`.\n5. `import Haneke` whenever you want to use Haneke.\n\n## Requirements\n\n- iOS 8.0+ or tvOS 9.1+\n- Swift 4\n\n## Using the cache\n\nHaneke provides shared caches for `UIImage`, `NSData`, `JSON` and `String`. You can also create your own caches.\n\nThe cache is a key-value store. For example, here's how you would cache and then fetch some data.\n\n```Swift\nlet cache = Shared.dataCache\n\ncache.set(value: data, key: \"funny-games.mp4\")\n\n\u002F\u002F Eventually...\n\ncache.fetch(key: \"funny-games.mp4\").onSuccess { data in\n    \u002F\u002F Do something with data\n}\n```\n\nIn most cases the value will not be readily available and will have to be fetched from network or disk. Haneke offers convenience `fetch` functions for these cases. Let's go back to the first example, now using a shared cache:\n\n```Swift\nlet cache = Shared.JSONCache\nlet URL = NSURL(string: \"https:\u002F\u002Fapi.github.com\u002Fusers\u002Fhaneke\")!\n\ncache.fetch(URL: URL).onSuccess { JSON in\n   print(JSON.dictionary?[\"bio\"])\n}\n```\n\nThe above call will first attempt to fetch the required JSON from (in order) memory, disk or `NSURLCache`. If not available, Haneke will fetch the JSON from the source, return it and then cache it. In this case, the URL itself is used as the key.\n\nFurther customization can be achieved by using [formats](#formats), [supporting additional types](#supporting-additional-types) or implementing [custom fetchers](#custom-fetchers).\n\n## Extra ♡ for images\n\nNeed to cache and display images? Haneke provides convenience methods for `UIImageView` and `UIButton` with optimizations for `UITableView` and `UICollectionView` cell reuse. Images will be resized appropriately and cached in a shared cache.\n\n```swift\n\u002F\u002F Setting a remote image\nimageView.hnk_setImageFromURL(url)\n\n\u002F\u002F Setting an image manually. Requires you to provide a key.\nimageView.hnk_setImage(image, key: key)\n```\n\nThe above lines take care of:\n\n1. If cached, retrieving an appropriately sized image (based on the `bounds` and `contentMode` of the `UIImageView`) from the memory or disk cache. Disk access is performed in background.\n2. If not cached, loading the original image from web\u002Fmemory and producing an appropriately sized image, both in background. Remote images will be retrieved from the shared `NSURLCache` if available.\n3. Setting the image and animating the change if appropriate.\n4. Or doing nothing if the `UIImageView` was reused during any of the above steps.\n5. Caching the resulting image.\n6. If needed, evicting the least recently used images in the cache.\n\n## Formats\n\nFormats allow to specify the disk cache size and any transformations to the values before being cached. For example, the `UIImageView` extension uses a format that resizes images to fit or fill the image view as needed.\n\nYou can also use custom formats. Say you want to limit the disk capacity for icons to 10MB and apply rounded corners to the images. This is how it could look like:\n\n```swift\nlet cache = Shared.imageCache\n\nlet iconFormat = Format\u003CUIImage>(name: \"icons\", diskCapacity: 10 * 1024 * 1024) { image in\n    return imageByRoundingCornersOfImage(image)\n}\ncache.addFormat(iconFormat)\n\nlet URL = NSURL(string: \"http:\u002F\u002Fhaneke.io\u002Ficon.png\")!\ncache.fetch(URL: URL, formatName: \"icons\").onSuccess { image in\n    \u002F\u002F image will be a nice rounded icon\n}\n```\n\nBecause we told the cache to use the `\"icons\"` format Haneke will execute the format transformation in background and return the resulting value.\n\nFormats can also be used from the `UIKit` extensions:\n\n```swift\nimageView.hnk_setImageFromURL(url, format: iconFormat)\n```\n\n## Fetchers\n\nThe `fetch` functions for urls and paths are actually convenience methods. Under the hood Haneke uses fetcher objects. To illustrate, here's another way of fetching from a url by explictly using a network fetcher:\n\n```swift\nlet URL = NSURL(string: \"http:\u002F\u002Fhaneke.io\u002Ficon.png\")!\nlet fetcher = NetworkFetcher\u003CUIImage>(URL: URL)\ncache.fetch(fetcher: fetcher).onSuccess { image in\n    \u002F\u002F Do something with image\n}\n```\n\nFetching an original value from network or disk is an expensive operation. Fetchers act as a proxy for the value, and allow Haneke to perform the fetch operation only if absolutely necessary.\n\nIn the above example the fetcher will be executed only if there is no value associated with `\"http:\u002F\u002Fhaneke.io\u002Ficon.png\"` in the memory or disk cache. If that happens, the fetcher will be responsible from fetching the original value, which will then be cached to avoid further network activity.\n\nHaneke provides two specialized fetchers: `NetworkFetcher\u003CT>` and `DiskFetcher\u003CT>`. You can also implement your own fetchers by subclassing `Fetcher\u003CT>`.\n\n### Custom fetchers\n\nThrough custom fetchers you can fetch original values from other sources than network or disk (e.g., Core Data), or even change how Haneke acceses network or disk (e.g., use [Alamofire](https:\u002F\u002Fgithub.com\u002FAlamofire\u002FAlamofire) for networking instead of `NSURLSession`). A custom fetcher must subclass `Fetcher\u003CT>` and is responsible for:\n\n* Providing the key (e.g., `NSURL.absoluteString` in the case of `NetworkFetcher`) associated with the value to be fetched\n* Fetching the value in background and calling the success or failure closure accordingly, both in the main queue\n* Cancelling the fetch on demand, if possible\n\nFetchers are generic, and the only restriction on their type is that it must implement `DataConvertible`.\n\n## Supporting additional types\n\nHaneke can cache any type that can be read and saved as data. This is indicated to Haneke by implementing the protocols `DataConvertible` and `DataRepresentable`.\n\n```Swift\npublic protocol DataConvertible {\n    typealias Result\n\n    class func convertFromData(data:NSData) -> Result?\n\n}\n\npublic protocol DataRepresentable {\n\n    func asData() -> NSData!\n\n}\n```\n\nThis is how one could add support for `NSDictionary`:\n\n```Swift\nextension NSDictionary : DataConvertible, DataRepresentable {\n\n    public typealias Result = NSDictionary\n\n    public class func convertFromData(data:NSData) -> Result? {\n        return NSKeyedUnarchiver.unarchiveObjectWithData(data) as? NSDictionary\n    }\n\n    public func asData() -> NSData! {\n        return NSKeyedArchiver.archivedDataWithRootObject(self)\n    }\n\n}\n```\n\nThen creating a `NSDictionary` cache would be as simple as:\n\n```swift\nlet cache = Cache\u003CNSDictionary>(name: \"dictionaries\")\n```\n\n## Roadmap\n\nHaneke Swift is in initial development and its public API should not be considered stable.\n\n## License\n\n Copyright 2014 Hermes Pique ([@hpique](https:\u002F\u002Ftwitter.com\u002Fhpique))    \n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2014 Joan Romano ([@joanromano](https:\u002F\u002Ftwitter.com\u002Fjoanromano))   \n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2014 Luis Ascorbe ([@lascorbe](https:\u002F\u002Ftwitter.com\u002FLascorbe))   \n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2014 Oriol Blanc ([@oriolblanc](https:\u002F\u002Ftwitter.com\u002Foriolblanc))   \n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http:\u002F\u002Fwww.apache.org\u002Flicenses\u002FLICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n","Haneke\u002FHanekeSwift 是一个为iOS和tvOS设计的轻量级通用缓存库，使用Swift编写，特别优化了图片处理。它支持多种数据类型（如UIImage、NSData、JSON、String等）的内存与磁盘缓存，并提供自动调整大小的零配置图像缓存功能。所有磁盘访问都在后台进行，确保了应用响应速度和流畅滚动体验。此外，Haneke还具备线程安全特性以及在内存警告或磁盘容量达到上限时自动清除缓存的能力。此项目非常适合需要高效缓存机制尤其是图片加载优化的应用场景。",2,"2026-06-11 03:09:10","top_language"]