From 4ffa34b9ab3468bf5dff18125b88cae46a6177bb Mon Sep 17 00:00:00 2001 From: Francesco <100066266+cranci1@users.noreply.github.com> Date: Mon, 2 Jun 2025 08:57:37 +0200 Subject: [PATCH] cachec --- Sora/Utils/Cache/KingfisherManager.swift | 66 ++++++++++--------- .../xcshareddata/swiftpm/Package.resolved | 9 --- 2 files changed, 35 insertions(+), 40 deletions(-) diff --git a/Sora/Utils/Cache/KingfisherManager.swift b/Sora/Utils/Cache/KingfisherManager.swift index 860d02c..d110d54 100644 --- a/Sora/Utils/Cache/KingfisherManager.swift +++ b/Sora/Utils/Cache/KingfisherManager.swift @@ -5,29 +5,23 @@ // Created by doomsboygaming on 5/22/25 // +import SwiftUI import Foundation import Kingfisher -import SwiftUI -/// Manages Kingfisher image caching configuration class KingfisherCacheManager { + private let jpegCompressionQuality: CGFloat = 0.7 + static let shared = KingfisherCacheManager() - - /// Maximum disk cache size (default 500MB) - private let maxDiskCacheSize: UInt = 500 * 1024 * 1024 - - /// Maximum cache age (default 7 days) + private let maxDiskCacheSize: UInt = 64 * 1024 * 1024 private let maxCacheAgeInDays: TimeInterval = 7 - /// UserDefaults keys private let imageCachingEnabledKey = "imageCachingEnabled" - /// Whether image caching is enabled var isCachingEnabled: Bool { get { - // Default to true if not set - UserDefaults.standard.object(forKey: imageCachingEnabledKey) == nil ? - true : UserDefaults.standard.bool(forKey: imageCachingEnabledKey) + UserDefaults.standard.object(forKey: imageCachingEnabledKey) == nil ? + true : UserDefaults.standard.bool(forKey: imageCachingEnabledKey) } set { UserDefaults.standard.set(newValue, forKey: imageCachingEnabledKey) @@ -37,31 +31,46 @@ class KingfisherCacheManager { private init() { configureKingfisher() +#if os(iOS) + NotificationCenter.default.addObserver(self, selector: #selector(clearMemoryCacheOnWarning), name: UIApplication.didReceiveMemoryWarningNotification, object: nil) +#endif + } + + @objc private func clearMemoryCacheOnWarning() { + KingfisherManager.shared.cache.clearMemoryCache() + Logger.shared.log("Cleared memory cache due to memory warning", type: "Debug") } - /// Configure Kingfisher with appropriate caching settings func configureKingfisher() { let cache = ImageCache.default - // Set disk cache size limit and expiration cache.diskStorage.config.sizeLimit = isCachingEnabled ? maxDiskCacheSize : 0 - cache.diskStorage.config.expiration = isCachingEnabled ? - .days(Int(maxCacheAgeInDays)) : .seconds(1) // 1 second means effectively disabled + cache.diskStorage.config.expiration = isCachingEnabled ? + .days(Int(maxCacheAgeInDays)) : .seconds(1) - // Set memory cache size - cache.memoryStorage.config.totalCostLimit = isCachingEnabled ? - 30 * 1024 * 1024 : 0 // 30MB memory cache when enabled + cache.memoryStorage.config.totalCostLimit = isCachingEnabled ? + 12 * 1024 * 1024 : 0 + + cache.memoryStorage.config.cleanInterval = 60 + + KingfisherManager.shared.downloader.downloadTimeout = 15.0 + + struct CustomJPEGCacheSerializer: CacheSerializer { + let compressionQuality: CGFloat - // Configure clean interval - cache.memoryStorage.config.cleanInterval = 60 // Clean memory every 60 seconds - - // Configure retry strategy - KingfisherManager.shared.downloader.downloadTimeout = 15.0 // 15 second timeout + func data(with image: KFCrossPlatformImage, original: Data?) -> Data? { + return image.kf.jpegData(compressionQuality: compressionQuality) + } + + func image(with data: Data, options: KingfisherParsedOptionsInfo) -> KFCrossPlatformImage? { + return DefaultCacheSerializer.default.image(with: data, options: options) + } + } + cache.diskStorage.config.cacheSerializer = CustomJPEGCacheSerializer(compressionQuality: jpegCompressionQuality) Logger.shared.log("Configured Kingfisher cache. Enabled: \(isCachingEnabled)", type: "Debug") } - /// Clear all cached images func clearCache(completion: (() -> Void)? = nil) { KingfisherManager.shared.cache.clearMemoryCache() KingfisherManager.shared.cache.clearDiskCache { @@ -70,8 +79,6 @@ class KingfisherCacheManager { } } - /// Calculate current cache size - /// - Parameter completion: Closure to call with cache size in bytes func calculateCacheSize(completion: @escaping (UInt) -> Void) { KingfisherManager.shared.cache.calculateDiskStorageSize { result in switch result { @@ -84,12 +91,9 @@ class KingfisherCacheManager { } } - /// Convert cache size to user-friendly string - /// - Parameter sizeInBytes: Size in bytes - /// - Returns: Formatted string (e.g., "5.2 MB") static func formatCacheSize(_ sizeInBytes: UInt) -> String { let formatter = ByteCountFormatter() formatter.countStyle = .file return formatter.string(fromByteCount: Int64(sizeInBytes)) } -} \ No newline at end of file +} diff --git a/Sulfur.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Sulfur.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index a843cd1..6bc3765 100644 --- a/Sulfur.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Sulfur.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -10,15 +10,6 @@ "version": null } }, - { - "package": "Kingfisher", - "repositoryURL": "https://github.com/onevcat/Kingfisher.git", - "state": { - "branch": null, - "revision": "b6f62758f21a8c03cd64f4009c037cfa580a256e", - "version": "7.9.1" - } - }, { "package": "MarqueeLabel", "repositoryURL": "https://github.com/cbpowell/MarqueeLabel",