Haneke Swift

cache librarySwiftiOStvOSimage cachemobileUIKit

Cache Library

Haneke Swift

Overview

Haneke Swift is a lightweight generic cache library for iOS and tvOS applications written in Swift 4. It excels at handling images with specialized features and implements a two-tier architecture combining memory and disk caching. It supports caching various data types including UIImage, NSData, JSON, String, and any custom types conforming to specific protocols.

Details

Haneke Swift provides an efficient caching system that combines fast memory cache (NSCache) with persistent LRU (Least Recently Used) disk cache. It particularly excels at image caching with features like automatic resizing, asynchronous background processing, and optimizations for cell reuse, providing comprehensive functionality needed for mobile application development.

Key Features

  • Generic Caching: Supports caching any type that conforms to DataConvertible and DataRepresentable protocols
  • Two-Tier Cache System: Combines fast memory cache with persistent disk cache
  • Image-Specific Features: Automatic resizing, decompression, and custom transformation capabilities
  • UIKit Integration: Easy integration with UIImageView and UIButton, optimized for cell reuse
  • Shared Instances: Pre-configured global cache access for common data types
  • Asynchronous Processing: Background image processing and file reading

Architecture

  • Cache: Central manager for cache operations, coordinating memory and disk caches, data transformations, and fetch orchestration
  • DiskCache: Persistent storage on file system with capacity management and LRU eviction policy
  • Format: Defines how data is transformed before caching (e.g., image resizing)
  • Fetcher: Abstract interface for retrieving data from various sources when not available in cache

Pros and Cons

Pros

  • Zero Configuration: Minimal setup required for image caching functionality
  • High Performance: Fast data access through two-tier memory and disk caching
  • UIKit Optimized: Optimized for UITableView and UICollectionView cell reuse
  • Thread-Safe: Guarantees safety during concurrent access
  • Flexible Customization: Extensible through custom formats and fetchers
  • Automatic Memory Management: Automatic cache clearing on memory warnings

Cons

  • iOS/tvOS Only: Limited to Apple platforms, no cross-platform support
  • Swift Only: Difficult to use directly with Objective-C
  • Learning Curve: Requires understanding to utilize advanced features effectively
  • Dependencies: UIKit dependency prevents server-side usage

Reference Links

Code Examples

Basic Cache Operations

import Haneke

// Using shared data cache
let cache = Shared.dataCache
cache.set(value: data, key: "movie-file.mp4")

// Fetching data
cache.fetch(key: "movie-file.mp4").onSuccess { data in
    print("Data retrieved successfully")
}

Image Caching Usage

// Loading image in UIImageView
imageView.hnk_setImageFromURL(url)

// Loading image with placeholder
imageView.hnk_setImageFromURL(url, placeholder: placeholderImage)

// Handling failure cases
imageView.hnk_setImageFromURL(url) { result in
    switch result {
    case .success(let image):
        print("Image loaded successfully")
    case .failure(let error):
        print("Loading failed: \(error)")
    }
}

JSON Cache Usage

// Creating JSON cache
let cache = Cache<JSON>(name: "api-cache")
let url = URL(string: "https://api.example.com/users")!

// Fetching and caching JSON from URL
cache.fetch(url: url).onSuccess { json in
    if let users = json.dictionary {
        // Process JSON data
        print("User count: \(users.count)")
    }
}

Custom Cache Creation

// Custom data type cache
struct User: DataConvertible, DataRepresentable {
    let id: Int
    let name: String
    
    static func convertFromData(_ data: Data) -> User? {
        // Implementation for converting Data to User object
        return try? JSONDecoder().decode(User.self, from: data)
    }
    
    func convertToData() -> Data? {
        // Implementation for converting User object to Data
        return try? JSONEncoder().encode(self)
    }
}

// Using custom cache
let userCache = Cache<User>(name: "users")
let user = User(id: 1, name: "Alice")

userCache.set(value: user, key: "user-1")
userCache.fetch(key: "user-1").onSuccess { user in
    print("User: \(user.name)")
}

Image Transformation with Formats

// Defining image format
let squareFormat = Format<UIImage>(name: "square") { image in
    // Process to crop to square
    let size = min(image.size.width, image.size.height)
    let squareSize = CGSize(width: size, height: size)
    // Resize image and return
    return image.hnk_imageByScaling(toSize: squareSize)
}

// Adding format to image cache
let imageCache = Shared.imageCache
imageCache.addFormat(squareFormat)

// Fetching image with format
imageView.hnk_setImageFromURL(url, format: squareFormat)

Cache Clearing

// Clear cache for specific key
cache.remove(key: "specific-key")

// Clear all cache
cache.removeAll()

// Clear shared image cache
Shared.imageCache.removeAll()