60 lines
2.0 KiB
Swift
60 lines
2.0 KiB
Swift
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()
|
|
}
|
|
} |