Caching system for loaded animations to improve performance and reduce memory usage by storing frequently used animations in memory for quick retrieval.
Protocol defining the interface for animation caching systems, enabling custom cache implementations.
/**
* Protocol for animation caching systems
* Enables performance optimization for repeated animation loads
*/
public protocol AnimationCacheProvider: AnyObject, Sendable {
/**
* Retrieve cached animation by key
* @param forKey - Cache key string
* @returns Cached LottieAnimation, nil if not found
*/
func animation(forKey: String) -> LottieAnimation?
/**
* Store animation in cache with key
* @param animation - LottieAnimation to cache
* @param forKey - Cache key string for retrieval
*/
func setAnimation(_ animation: LottieAnimation, forKey: String)
/**
* Remove all cached animations
* Frees memory used by cached animations
*/
func clearCache()
}Global configuration point for animation caching, allowing customization of the cache provider used throughout the library.
/**
* Global animation cache configuration
* Customization point for which cache provider is used
*/
public enum LottieAnimationCache {
/**
* The animation cache provider used when loading animations
* Defaults to DefaultAnimationCache.sharedCache
* Set to nil to disable caching entirely
*/
public static var shared: AnimationCacheProvider?
}Usage Examples:
import Lottie
// Use default cache (recommended)
let animation = LottieAnimation.named("my-animation") // Uses cache automatically
// Disable caching globally
LottieAnimationCache.shared = nil
// Use custom cache implementation
class CustomAnimationCache: AnimationCacheProvider {
private var storage: [String: LottieAnimation] = [:]
func animation(forKey key: String) -> LottieAnimation? {
return storage[key]
}
func setAnimation(_ animation: LottieAnimation, forKey key: String) {
storage[key] = animation
}
func clearCache() {
storage.removeAll()
}
}
LottieAnimationCache.shared = CustomAnimationCache()Thread-safe LRU (Least Recently Used) cache implementation with configurable size limits and memory pressure handling.
/**
* Default thread-safe animation cache implementation
* Uses LRU eviction policy with configurable size limits
*/
public class DefaultAnimationCache: AnimationCacheProvider {
// MARK: - Shared Instance
/** Global shared cache instance */
public static let sharedCache: DefaultAnimationCache
// MARK: - Initializers
/**
* Create new cache instance with default settings
* Default cache size is 100 animations
*/
public init()
// MARK: - Configuration
/**
* Maximum number of animations stored in cache
* When limit is reached, least recently used animations are ejected
*/
public var cacheSize: Int { get set }
// MARK: - Cache Operations
/**
* Clear all cached animations
* Frees memory used by all cached animations
*/
public func clearCache()
/**
* Retrieve animation from cache
* @param key - Cache key string
* @returns Cached animation, nil if not found
*/
public func animation(forKey key: String) -> LottieAnimation?
/**
* Store animation in cache
* @param animation - Animation to cache
* @param key - Cache key for retrieval
*/
public func setAnimation(_ animation: LottieAnimation, forKey key: String)
}Usage Examples:
import Lottie
// Configure shared cache
DefaultAnimationCache.sharedCache.cacheSize = 50 // Limit to 50 animations
// Manual cache operations
let cache = DefaultAnimationCache.sharedCache
// Check if animation is cached
if let cachedAnimation = cache.animation(forKey: "button-animation") {
// Use cached animation
let animationView = LottieAnimationView(animation: cachedAnimation)
} else {
// Load and cache animation
if let animation = LottieAnimation.named("button-animation") {
cache.setAnimation(animation, forKey: "button-animation")
let animationView = LottieAnimationView(animation: animation)
}
}
// Clear cache when memory is low
cache.clearCache()
// Create custom cache instance
let customCache = DefaultAnimationCache()
customCache.cacheSize = 200 // Larger cache for this instanceThe cache system integrates seamlessly with animation loading methods, automatically caching animations when loaded.
// Animation loading methods that use cache automatically
extension LottieAnimation {
/**
* Load animation with automatic caching
* Uses LottieAnimationCache.shared if available
*/
public static func named(
_ name: String,
bundle: Bundle = Bundle.main,
subdirectory: String? = nil,
animationCache: AnimationCacheProvider? = LottieAnimationCache.shared
) -> LottieAnimation?
/**
* Load animation from file path with caching
*/
public static func filepath(
_ filepath: String,
animationCache: AnimationCacheProvider? = LottieAnimationCache.shared
) -> LottieAnimation?
}Usage Examples:
// Automatic caching (recommended approach)
let animation1 = LottieAnimation.named("loading") // Loads and caches
let animation2 = LottieAnimation.named("loading") // Retrieved from cache
// Explicit cache control
let animation3 = LottieAnimation.named("no-cache", animationCache: nil) // Skip cache
// Custom cache for specific animation
let customCache = DefaultAnimationCache()
let animation4 = LottieAnimation.named("special", animationCache: customCache)// Small apps with few animations
DefaultAnimationCache.sharedCache.cacheSize = 20
// Medium apps with moderate animation usage
DefaultAnimationCache.sharedCache.cacheSize = 100 // Default
// Large apps with many animations
DefaultAnimationCache.sharedCache.cacheSize = 300
// Memory-constrained environments (widgets, extensions)
DefaultAnimationCache.sharedCache.cacheSize = 5
LottieAnimationCache.shared = nil // Or disable entirelyCache keys are automatically generated based on:
named(_:) loadingfilepath(_:) loading// Custom cache with performance monitoring
class MonitoredCache: AnimationCacheProvider {
private let underlyingCache = DefaultAnimationCache()
private var hitCount = 0
private var missCount = 0
func animation(forKey key: String) -> LottieAnimation? {
if let animation = underlyingCache.animation(forKey: key) {
hitCount += 1
return animation
} else {
missCount += 1
return nil
}
}
func setAnimation(_ animation: LottieAnimation, forKey key: String) {
underlyingCache.setAnimation(animation, forKey: key)
}
func clearCache() {
underlyingCache.clearCache()
hitCount = 0
missCount = 0
}
var hitRatio: Double {
let total = hitCount + missCount
return total > 0 ? Double(hitCount) / Double(total) : 0
}
}