import Foundation import UIKit class GIFFileManager { static let shared = GIFFileManager() private init() { createGIFsDirectoryIfNeeded() } // MARK: - File Storage private var documentsDirectory: URL { let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) return paths[0] } private var gifsDirectory: URL { return documentsDirectory.appendingPathComponent("SavedGIFs", isDirectory: true) } private func createGIFsDirectoryIfNeeded() { let fileManager = FileManager.default if !fileManager.fileExists(atPath: gifsDirectory.path) { do { try fileManager.createDirectory(at: gifsDirectory, withIntermediateDirectories: true) } catch { print("Error creating GIFs directory: \(error)") } } } func storeGIF(data: Data, fromURL urlString: String) -> String? { // Create a unique filename based on the URL hash and timestamp let urlHash = urlString.hashValue let timestamp = Int(Date().timeIntervalSince1970) let filename = "gif_\(urlHash)_\(timestamp).gif" let fileURL = gifsDirectory.appendingPathComponent(filename) do { try data.write(to: fileURL) return fileURL.path } catch { print("Error saving GIF to disk: \(error)") return nil } } func loadGIFData(from localPath: String) -> Data? { let url = URL(fileURLWithPath: localPath) do { let data = try Data(contentsOf: url) return data } catch { print("Error loading GIF from disk: \(error)") return nil } } func deleteGIF(at localPath: String) -> Bool { let fileManager = FileManager.default do { try fileManager.removeItem(atPath: localPath) return true } catch { print("Error deleting GIF from disk: \(error)") return false } } func fileExists(at localPath: String) -> Bool { return FileManager.default.fileExists(atPath: localPath) } func getAllGIFsSize() -> Int64 { let fileManager = FileManager.default let enumerator = fileManager.enumerator(at: gifsDirectory, includingPropertiesForKeys: [.fileSizeKey]) var totalSize: Int64 = 0 while let fileURL = enumerator?.nextObject() as? URL { do { let attributes = try fileURL.resourceValues(forKeys: [.fileSizeKey]) if let fileSize = attributes.fileSize { totalSize += Int64(fileSize) } } catch { print("Error calculating file size: \(error)") } } return totalSize } // Clean up old GIFs if storage exceeds 100 MB func performStorageCleanupIfNeeded() { let maxStorageSize: Int64 = 100 * 1024 * 1024 // 100 MB if getAllGIFsSize() > maxStorageSize { cleanupOldGIFs() } } private func cleanupOldGIFs() { let fileManager = FileManager.default do { // Get all files and their creation dates let fileURLs = try fileManager.contentsOfDirectory(at: gifsDirectory, includingPropertiesForKeys: [.creationDateKey]) // Sort by creation date let sortedFiles = try fileURLs.sorted { let date1 = try $0.resourceValues(forKeys: [.creationDateKey]).creationDate ?? Date.distantPast let date2 = try $1.resourceValues(forKeys: [.creationDateKey]).creationDate ?? Date.distantPast return date1 < date2 } // Delete the oldest 30% of files let filesToDelete = Int(Double(sortedFiles.count) * 0.3) for i in 0..