Haneke Swift

キャッシュライブラリSwiftiOStvOS画像キャッシュモバイルUIKit

キャッシュライブラリ

Haneke Swift

概要

Haneke SwiftはiOSおよびtvOS向けの軽量なジェネリックキャッシュライブラリです。Swift 4で書かれており、特に画像の扱いに特化した機能を持っています。メモリキャッシュとディスクキャッシュの二層構造を採用し、UIImageNSDataJSONStringなど様々なデータ型のキャッシュに対応しています。

詳細

Haneke Swiftは、高速なメモリキャッシュ(NSCache)と持続性のあるLRU(Least Recently Used)ディスクキャッシュを組み合わせた効率的なキャッシュシステムを提供します。特に画像キャッシュに優れており、自動的なリサイズ、非同期での背景処理、セルの再利用への最適化など、モバイルアプリケーション開発に必要な機能を包括的にサポートしています。

主要な特徴

  • ジェネリックキャッシュ: DataConvertibleDataRepresentableプロトコルに準拠した任意の型をキャッシュ可能
  • 二層キャッシュシステム: 高速なメモリキャッシュと永続的なディスクキャッシュの組み合わせ
  • 画像特化機能: 自動リサイズ、デコンプレッション、カスタム変換機能
  • UIKit統合: UIImageViewUIButtonへの簡単な統合とセル再利用の最適化
  • 共有インスタンス: 一般的なデータ型への事前設定されたグローバルキャッシュアクセス
  • 非同期処理: バックグラウンドでの画像処理とファイル読み込み

アーキテクチャ

  • Cache: キャッシュ操作の中央管理者。メモリとディスクキャッシュの調整、データ変換、フェッチの管理を行う
  • DiskCache: ファイルシステムでの永続ストレージ、容量管理、LRU削除ポリシー
  • Format: データがキャッシュされる前の変換方法を定義(画像のリサイズなど)
  • Fetcher: キャッシュにないデータを様々なソースから取得するための抽象インターフェース

メリット・デメリット

メリット

  • ゼロ設定での利用: 最小限の設定で画像キャッシュが利用可能
  • 高いパフォーマンス: メモリとディスクの二層キャッシュによる高速データアクセス
  • UIKit最適化: UITableViewやUICollectionViewでのセル再利用に最適化
  • スレッドセーフ: 並行アクセス時の安全性を保証
  • 柔軟なカスタマイズ: カスタムフォーマットやフェッチャーによる拡張可能性
  • 自動メモリ管理: メモリ警告時の自動的なキャッシュクリア

デメリット

  • iOS/tvOS限定: Appleプラットフォーム専用でクロスプラットフォーム対応なし
  • Swift専用: Objective-Cでの直接利用は困難
  • 学習コストあり: 高度な機能を活用するには相応の理解が必要
  • 依存関係: UIKitへの依存によりサーバーサイドでの利用不可

参考ページ

書き方の例

基本的なキャッシュ操作

import Haneke

// 共有データキャッシュの利用
let cache = Shared.dataCache
cache.set(value: data, key: "movie-file.mp4")

// データの取得
cache.fetch(key: "movie-file.mp4").onSuccess { data in
    print("データを取得しました")
}

画像キャッシュの利用

// UIImageViewでの画像読み込み
imageView.hnk_setImageFromURL(url)

// プレースホルダー付きの画像読み込み
imageView.hnk_setImageFromURL(url, placeholder: placeholderImage)

// 失敗時の処理
imageView.hnk_setImageFromURL(url) { result in
    switch result {
    case .success(let image):
        print("画像読み込み成功")
    case .failure(let error):
        print("読み込み失敗: \(error)")
    }
}

JSONキャッシュの利用

// JSONキャッシュの作成
let cache = Cache<JSON>(name: "api-cache")
let url = URL(string: "https://api.example.com/users")!

// URLからJSONを取得・キャッシュ
cache.fetch(url: url).onSuccess { json in
    if let users = json.dictionary {
        // JSONデータの処理
        print("ユーザー数: \(users.count)")
    }
}

カスタムキャッシュの作成

// カスタムデータ型のキャッシュ
struct User: DataConvertible, DataRepresentable {
    let id: Int
    let name: String
    
    static func convertFromData(_ data: Data) -> User? {
        // データからUserオブジェクトへの変換実装
        return try? JSONDecoder().decode(User.self, from: data)
    }
    
    func convertToData() -> Data? {
        // UserオブジェクトからDataへの変換実装
        return try? JSONEncoder().encode(self)
    }
}

// カスタムキャッシュの利用
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.name)")
}

フォーマットを使用した画像変換

// 画像フォーマットの定義
let squareFormat = Format<UIImage>(name: "square") { image in
    // 正方形にクロップする処理
    let size = min(image.size.width, image.size.height)
    let squareSize = CGSize(width: size, height: size)
    // 画像をリサイズして返す
    return image.hnk_imageByScaling(toSize: squareSize)
}

// 画像キャッシュにフォーマットを追加
let imageCache = Shared.imageCache
imageCache.addFormat(squareFormat)

// フォーマット付きで画像を取得
imageView.hnk_setImageFromURL(url, format: squareFormat)

キャッシュクリア

// 特定のキーのキャッシュをクリア
cache.remove(key: "specific-key")

// 全てのキャッシュをクリア
cache.removeAll()

// 共有画像キャッシュのクリア
Shared.imageCache.removeAll()