2024-07-12 11:54:40 +00:00
|
|
|
import Foundation
|
|
|
|
|
|
|
|
final class DownloadManager {
|
2024-07-13 01:29:46 +00:00
|
|
|
static let shared = DownloadManager()
|
|
|
|
|
2024-07-12 11:54:40 +00:00
|
|
|
private let urlSession: URLSession
|
2024-07-13 01:29:46 +00:00
|
|
|
private let downloadQueue = DispatchQueue(label: "com.example.downloadQueue")
|
|
|
|
private var activeDownloads = Set<URL>()
|
2024-07-12 11:54:40 +00:00
|
|
|
|
|
|
|
init() {
|
|
|
|
let configuration = URLSessionConfiguration.default
|
|
|
|
urlSession = URLSession(configuration: configuration)
|
|
|
|
}
|
|
|
|
|
2024-07-13 01:29:46 +00:00
|
|
|
func enqueueDownload(from url: URL, to localUrl: URL, completion: @escaping (Error?) -> Void) {
|
|
|
|
downloadQueue.async {
|
|
|
|
if self.activeDownloads.contains(url) {
|
|
|
|
print("Download for this file is already in queue.")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
self.activeDownloads.insert(url)
|
|
|
|
|
|
|
|
let task = self.urlSession.downloadTask(with: url) { tempLocalUrl, _, error in
|
|
|
|
self.downloadQueue.async {
|
|
|
|
self.activeDownloads.remove(url)
|
|
|
|
|
|
|
|
if let tempLocalUrl = tempLocalUrl, error == nil {
|
|
|
|
do {
|
2024-07-13 15:02:57 +00:00
|
|
|
if FileManager.default.fileExists(atPath: localUrl.path) {
|
|
|
|
try FileManager.default.removeItem(at: localUrl)
|
|
|
|
}
|
2024-07-13 16:29:08 +00:00
|
|
|
try FileManager.default.moveItem(at: tempLocalUrl, to: localUrl)
|
2024-07-13 01:29:46 +00:00
|
|
|
completion(nil)
|
|
|
|
} catch let writeError {
|
|
|
|
completion(writeError)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
completion(error)
|
|
|
|
}
|
2024-07-12 11:54:40 +00:00
|
|
|
}
|
|
|
|
}
|
2024-07-13 01:29:46 +00:00
|
|
|
task.resume()
|
2024-07-12 11:54:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|