init, finished
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
class GIFDownloadService {
|
||||
static let shared = GIFDownloadService()
|
||||
|
||||
private let cache = NSCache<NSString, NSData>()
|
||||
private var activeTasks: [URL: URLSessionDataTask] = [:]
|
||||
|
||||
private init() {
|
||||
cache.totalCostLimit = 100 * 1024 * 1024 // 100 MB cache limit
|
||||
}
|
||||
|
||||
func downloadGIF(from urlString: String, completion: @escaping (Data?, Error?) -> Void) {
|
||||
guard let url = URL(string: urlString) else {
|
||||
completion(nil, NSError(domain: "GIFDownloadService", code: 1, userInfo: [NSLocalizedDescriptionKey: "Invalid URL"]))
|
||||
return
|
||||
}
|
||||
|
||||
// Check if the GIF is already cached
|
||||
let cacheKey = url.absoluteString as NSString
|
||||
if let cachedData = cache.object(forKey: cacheKey) {
|
||||
completion(cachedData as Data, nil)
|
||||
return
|
||||
}
|
||||
|
||||
// Cancel any existing tasks for this URL
|
||||
activeTasks[url]?.cancel()
|
||||
|
||||
// Create a new download task
|
||||
let task = URLSession.shared.dataTask(with: url) { [weak self] data, response, error in
|
||||
defer {
|
||||
self?.activeTasks.removeValue(forKey: url)
|
||||
}
|
||||
|
||||
guard let self = self, error == nil, let data = data else {
|
||||
DispatchQueue.main.async {
|
||||
completion(nil, error ?? NSError(domain: "GIFDownloadService", code: 2, userInfo: [NSLocalizedDescriptionKey: "Failed to download GIF"]))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Cache the downloaded data
|
||||
self.cache.setObject(data as NSData, forKey: cacheKey, cost: data.count)
|
||||
|
||||
DispatchQueue.main.async {
|
||||
completion(data, nil)
|
||||
}
|
||||
}
|
||||
|
||||
// Store and start the task
|
||||
activeTasks[url] = task
|
||||
task.resume()
|
||||
}
|
||||
|
||||
func cancelAllTasks() {
|
||||
activeTasks.values.forEach { $0.cancel() }
|
||||
activeTasks.removeAll()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import Foundation
|
||||
|
||||
class GIFStorageService {
|
||||
static let shared = GIFStorageService()
|
||||
|
||||
private let userDefaults = UserDefaults(suiteName: "group.gifcollector")
|
||||
private let savedGIFsKey = "savedGIFs"
|
||||
|
||||
private init() {
|
||||
// Make sure the shared UserDefaults exists
|
||||
if userDefaults == nil {
|
||||
print("Error: Could not create UserDefaults with app group")
|
||||
}
|
||||
}
|
||||
|
||||
func saveGIF(_ gif: GIF) {
|
||||
var savedGIFs = fetchGIFs()
|
||||
|
||||
// Don't save duplicate URLs
|
||||
if !savedGIFs.contains(where: { $0.urlString == gif.urlString }) {
|
||||
savedGIFs.append(gif)
|
||||
saveToUserDefaults(gifs: savedGIFs)
|
||||
}
|
||||
}
|
||||
|
||||
func fetchGIFs() -> [GIF] {
|
||||
guard let data = userDefaults?.data(forKey: savedGIFsKey),
|
||||
let gifs = try? JSONDecoder().decode([GIF].self, from: data) else {
|
||||
return []
|
||||
}
|
||||
|
||||
return gifs.sorted(by: { $0.createdAt > $1.createdAt })
|
||||
}
|
||||
|
||||
func deleteGIF(with id: UUID) {
|
||||
var savedGIFs = fetchGIFs()
|
||||
savedGIFs.removeAll(where: { $0.id == id })
|
||||
saveToUserDefaults(gifs: savedGIFs)
|
||||
}
|
||||
|
||||
func clearAllGIFs() {
|
||||
saveToUserDefaults(gifs: [])
|
||||
}
|
||||
|
||||
private func saveToUserDefaults(gifs: [GIF]) {
|
||||
guard let data = try? JSONEncoder().encode(gifs) else { return }
|
||||
userDefaults?.set(data, forKey: savedGIFsKey)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user