Convert Figma logo to code with AI

Haneke logoHanekeSwift

A lightweight generic cache for iOS written in Swift with extra love for images.

5,203
591
5,203
98

Top Related Projects

A lightweight, pure-Swift library for downloading and caching images from the web.

Asynchronous image downloader with cache support as a UIImageView category

8,040

Image loading system

2,963

:package: Nothing but Cache.

Promises for Swift & ObjC.

AlamofireImage is an image component library for Alamofire

Quick Overview

HanekeSwift is a lightweight generic cache for iOS written in Swift. It's designed to be simple to use while offering powerful features like asynchronous fetching, format-independent caching, and automatic cache eviction based on memory pressure.

Pros

  • Easy to use with a simple API
  • Supports various types of data (images, JSON, strings, etc.)
  • Efficient memory management with automatic cache eviction
  • Asynchronous fetching and disk persistence

Cons

  • Limited active maintenance (last commit was in 2019)
  • May not be fully compatible with the latest Swift versions
  • Lacks some advanced features found in more comprehensive caching libraries
  • Documentation could be more extensive

Code Examples

  1. Caching and retrieving an image:
let cache = Haneke.Shared.imageCache
let URL = URL(string: "https://example.com/image.jpg")!

cache.fetch(URL: URL).onSuccess { image in
    imageView.image = image
}
  1. Caching and retrieving JSON data:
let cache = Haneke.Shared.jsonCache
let URL = URL(string: "https://api.example.com/data.json")!

cache.fetch(URL: URL).onSuccess { json in
    // Use the JSON data
    print(json)
}
  1. Caching a custom object:
struct MyObject: Codable {}

let cache = Cache<MyObject>(name: "myObjectCache")
let key = "uniqueKey"
let myObject = MyObject()

cache.set(value: myObject, key: key)
cache.fetch(key: key).onSuccess { object in
    // Use the retrieved object
    print(object)
}

Getting Started

  1. Add HanekeSwift to your project using Swift Package Manager:
dependencies: [
    .package(url: "https://github.com/Haneke/HanekeSwift.git", from: "0.13.0")
]
  1. Import Haneke in your Swift file:
import Haneke
  1. Use the shared cache or create a custom one:
let imageCache = Haneke.Shared.imageCache
// or
let customCache = Cache<String>(name: "customCache")
  1. Start caching and fetching data:
let URL = URL(string: "https://example.com/data")!
customCache.fetch(URL: URL).onSuccess { data in
    // Use the fetched data
}

Competitor Comparisons

A lightweight, pure-Swift library for downloading and caching images from the web.

Pros of Kingfisher

  • More actively maintained with frequent updates and bug fixes
  • Supports a wider range of image formats and caching options
  • Better performance for large image libraries and complex UI

Cons of Kingfisher

  • Larger library size, which may impact app size
  • Steeper learning curve due to more advanced features
  • May be overkill for simple image loading tasks

Code Comparison

HanekeSwift:

let imageView = UIImageView()
imageView.hnk_setImageFromURL(url)

Kingfisher:

let imageView = UIImageView()
imageView.kf.setImage(with: url)

Both libraries offer simple one-line image loading, but Kingfisher provides more customization options:

imageView.kf.setImage(with: url,
                      placeholder: placeholderImage,
                      options: [.transition(.fade(0.2))])

HanekeSwift is more lightweight and easier to use for basic image loading tasks, while Kingfisher offers more advanced features and better performance for complex applications. The choice between the two depends on the specific requirements of your project and the level of customization needed for image loading and caching.

Asynchronous image downloader with cache support as a UIImageView category

Pros of SDWebImage

  • More comprehensive feature set, including GIF and video support
  • Larger community and more frequent updates
  • Better documentation and extensive customization options

Cons of SDWebImage

  • Larger library size, which may impact app size
  • Steeper learning curve due to more complex API

Code Comparison

SDWebImage:

let imageView = UIImageView()
imageView.sd_setImage(with: URL(string: "https://example.com/image.jpg"))

HanekeSwift:

let imageView = UIImageView()
imageView.hnk_setImage(from: URL(string: "https://example.com/image.jpg"))

Key Differences

  • SDWebImage offers more advanced features and customization options
  • HanekeSwift is simpler and more lightweight
  • SDWebImage has better support for various image formats and caching mechanisms
  • HanekeSwift focuses on simplicity and ease of use

Performance

  • SDWebImage generally performs better for complex image loading scenarios
  • HanekeSwift may have a slight edge in simple use cases due to its lightweight nature

Community and Support

  • SDWebImage has a larger and more active community
  • More third-party extensions and integrations available for SDWebImage
  • HanekeSwift has less frequent updates and smaller community support

Integration

Both libraries are easy to integrate using CocoaPods or Carthage, but SDWebImage offers more flexibility in terms of modular integration of specific features.

8,040

Image loading system

Pros of Nuke

  • More actively maintained with frequent updates
  • Supports SwiftUI and Combine
  • Offers more advanced features like prefetching and progressive image loading

Cons of Nuke

  • Steeper learning curve due to more complex API
  • Larger codebase, which may increase app size
  • May be overkill for simpler image loading needs

Code Comparison

HanekeSwift:

let imageView = UIImageView()
imageView.hnk_setImageFromURL(url)

Nuke:

let imageView = UIImageView()
Nuke.loadImage(with: url, into: imageView)

Both libraries offer simple one-line image loading, but Nuke provides more customization options:

let options = ImageLoadingOptions(
    placeholder: UIImage(named: "placeholder"),
    transition: .fadeIn(duration: 0.33)
)
Nuke.loadImage(with: url, options: options, into: imageView)

HanekeSwift and Nuke are both image loading and caching libraries for iOS. HanekeSwift is simpler and easier to use for basic image loading tasks, while Nuke offers more advanced features and better performance for complex applications. The choice between them depends on the specific needs of your project and the level of control you require over image loading and caching processes.

2,963

:package: Nothing but Cache.

Pros of Cache

  • More actively maintained with recent updates
  • Supports multiple storage types (memory, disk, hybrid)
  • Offers more advanced features like expiration dates and cost calculation

Cons of Cache

  • Steeper learning curve due to more complex API
  • Larger codebase, potentially impacting app size
  • May be overkill for simple caching needs

Code Comparison

HanekeSwift:

let cache = Haneke.sharedCache
cache.set(value: image, key: "myImage")
cache.fetch(key: "myImage").onSuccess { image in
    // Use the cached image
}

Cache:

let storage = try? Storage<String, Image>(
    diskConfig: DiskConfig(name: "Images"),
    memoryConfig: MemoryConfig(),
    transformer: TransformerFactory.forImage()
)
try? storage?.async.setObject(image, forKey: "myImage")
storage?.async.object(forKey: "myImage") { result in
    // Handle the result
}

Both libraries provide caching solutions for Swift applications, but Cache offers more flexibility and features at the cost of increased complexity. HanekeSwift is simpler to use but has fewer options for customization. The choice between them depends on the specific needs of your project.

Promises for Swift & ObjC.

Pros of PromiseKit

  • Broader scope: Handles asynchronous programming and chaining of operations
  • More active development: Regular updates and larger community support
  • Extensive documentation and examples available

Cons of PromiseKit

  • Steeper learning curve for developers new to promises
  • Larger codebase and potential overhead for simpler projects
  • May require additional configuration for certain use cases

Code Comparison

HanekeSwift (Image caching):

let cache = Haneke.sharedCache
cache.fetch(URL: imageURL).onSuccess { image in
    imageView.image = image
}

PromiseKit (Asynchronous operations):

firstly {
    fetchUser()
}.then { user in
    fetchAvatar(for: user)
}.done { avatar in
    self.imageView.image = avatar
}.catch { error in
    print("Error: \(error)")
}

HanekeSwift focuses on image caching and provides a simpler API for that specific use case. PromiseKit offers a more versatile solution for handling various asynchronous operations and chaining them together. While HanekeSwift is more lightweight and easier to implement for image-related tasks, PromiseKit provides greater flexibility and power for complex asynchronous workflows across different domains.

AlamofireImage is an image component library for Alamofire

Pros of AlamofireImage

  • Integrated with Alamofire for seamless networking and image loading
  • More active development and community support
  • Extensive documentation and examples

Cons of AlamofireImage

  • Larger dependency footprint due to Alamofire integration
  • Potentially more complex setup for simple image caching needs
  • May be overkill for projects not already using Alamofire

Code Comparison

HanekeSwift:

let cache = Haneke.sharedCache
cache.fetch(URL: url).onSuccess { image in
    imageView.image = image
}

AlamofireImage:

let imageView = UIImageView(frame: frame)
imageView.af.setImage(withURL: url)

Summary

AlamofireImage is a powerful image loading and caching library that integrates well with Alamofire for networking tasks. It offers more features and active development compared to HanekeSwift. However, HanekeSwift provides a simpler, lightweight solution for basic image caching needs. AlamofireImage may be preferable for projects already using Alamofire or requiring advanced image handling capabilities, while HanekeSwift could be a better choice for smaller projects or those prioritizing simplicity.

Convert Figma logo designs to code with AI

Visual Copilot

Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.

Try Visual Copilot

README

Haneke

Carthage compatible SwiftPM compatible Accio supported Platform Build Status Join the chat at https://gitter.im/Haneke/HanekeSwift

Haneke 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:

let cache = Cache<JSON>(name: "github")
let URL = NSURL(string: "https://api.github.com/users/haneke")!

cache.fetch(URL: URL).onSuccess { JSON in
    print(JSON.dictionary?["bio"])
}

Haneke provides a memory and LRU disk cache for UIImage, NSData, JSON, String or any other type that can be read or written as data.

Particularly, 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:

imageView.hnk_setImageFromURL(url)

Really.

Features

  • Generic cache with out-of-the-box support for UIImage, NSData, JSON and String
  • First-level memory cache using NSCache
  • Second-level LRU disk cache using the file system
  • Asynchronous fetching of original values from network or disk
  • All disk access is performed in background
  • Thread-safe
  • Automatic cache eviction on memory warnings or disk capacity reached
  • Comprehensive unit tests
  • Extensible by defining custom formats, supporting additional types or implementing custom fetchers

For images:

  • Zero-config UIImageView and UIButton extensions to use the cache, optimized for UITableView and UICollectionView cell reuse
  • Background image resizing and decompression

Installation

Using CocoaPods:

use_frameworks!
pod 'HanekeSwift'

Using Carthage:

github "Haneke/HanekeSwift"

Using SwiftPM or Accio:

.package(url: "https://github.com/Haneke/HanekeSwift.git", .upToNextMajor(from: "0.11.2")),

Then link Haneke in your App target like so:

.target(
    name: "App",
    dependencies: [
        "Haneke",
    ]
),

Manually:

  1. Drag Haneke.xcodeproj to your project in the Project Navigator.
  2. Select your project and then your app target. Open the Build Phases panel.
  3. Expand the Target Dependencies group, and add Haneke.framework.
  4. 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.
  5. import Haneke whenever you want to use Haneke.

Requirements

  • iOS 8.0+ or tvOS 9.1+
  • Swift 4

Using the cache

Haneke provides shared caches for UIImage, NSData, JSON and String. You can also create your own caches.

The cache is a key-value store. For example, here's how you would cache and then fetch some data.

let cache = Shared.dataCache

cache.set(value: data, key: "funny-games.mp4")

// Eventually...

cache.fetch(key: "funny-games.mp4").onSuccess { data in
    // Do something with data
}

In 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:

let cache = Shared.JSONCache
let URL = NSURL(string: "https://api.github.com/users/haneke")!

cache.fetch(URL: URL).onSuccess { JSON in
   print(JSON.dictionary?["bio"])
}

The 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.

Further customization can be achieved by using formats, supporting additional types or implementing custom fetchers.

Extra ♡ for images

Need 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.

// Setting a remote image
imageView.hnk_setImageFromURL(url)

// Setting an image manually. Requires you to provide a key.
imageView.hnk_setImage(image, key: key)

The above lines take care of:

  1. 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.
  2. If not cached, loading the original image from web/memory and producing an appropriately sized image, both in background. Remote images will be retrieved from the shared NSURLCache if available.
  3. Setting the image and animating the change if appropriate.
  4. Or doing nothing if the UIImageView was reused during any of the above steps.
  5. Caching the resulting image.
  6. If needed, evicting the least recently used images in the cache.

Formats

Formats 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.

You 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:

let cache = Shared.imageCache

let iconFormat = Format<UIImage>(name: "icons", diskCapacity: 10 * 1024 * 1024) { image in
    return imageByRoundingCornersOfImage(image)
}
cache.addFormat(iconFormat)

let URL = NSURL(string: "http://haneke.io/icon.png")!
cache.fetch(URL: URL, formatName: "icons").onSuccess { image in
    // image will be a nice rounded icon
}

Because we told the cache to use the "icons" format Haneke will execute the format transformation in background and return the resulting value.

Formats can also be used from the UIKit extensions:

imageView.hnk_setImageFromURL(url, format: iconFormat)

Fetchers

The 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:

let URL = NSURL(string: "http://haneke.io/icon.png")!
let fetcher = NetworkFetcher<UIImage>(URL: URL)
cache.fetch(fetcher: fetcher).onSuccess { image in
    // Do something with image
}

Fetching 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.

In the above example the fetcher will be executed only if there is no value associated with "http://haneke.io/icon.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.

Haneke provides two specialized fetchers: NetworkFetcher<T> and DiskFetcher<T>. You can also implement your own fetchers by subclassing Fetcher<T>.

Custom fetchers

Through 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 for networking instead of NSURLSession). A custom fetcher must subclass Fetcher<T> and is responsible for:

  • Providing the key (e.g., NSURL.absoluteString in the case of NetworkFetcher) associated with the value to be fetched
  • Fetching the value in background and calling the success or failure closure accordingly, both in the main queue
  • Cancelling the fetch on demand, if possible

Fetchers are generic, and the only restriction on their type is that it must implement DataConvertible.

Supporting additional types

Haneke can cache any type that can be read and saved as data. This is indicated to Haneke by implementing the protocols DataConvertible and DataRepresentable.

public protocol DataConvertible {
    typealias Result

    class func convertFromData(data:NSData) -> Result?

}

public protocol DataRepresentable {

    func asData() -> NSData!

}

This is how one could add support for NSDictionary:

extension NSDictionary : DataConvertible, DataRepresentable {

    public typealias Result = NSDictionary

    public class func convertFromData(data:NSData) -> Result? {
        return NSKeyedUnarchiver.unarchiveObjectWithData(data) as? NSDictionary
    }

    public func asData() -> NSData! {
        return NSKeyedArchiver.archivedDataWithRootObject(self)
    }

}

Then creating a NSDictionary cache would be as simple as:

let cache = Cache<NSDictionary>(name: "dictionaries")

Roadmap

Haneke Swift is in initial development and its public API should not be considered stable.

License

Copyright 2014 Hermes Pique (@hpique)
                 2014 Joan Romano (@joanromano)
                 2014 Luis Ascorbe (@lascorbe)
                 2014 Oriol Blanc (@oriolblanc)

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.