Music_Player3/MusicPlayer/MP/Common/Tool(工具封装)/MP_DownloadManager.swift

119 lines
4.8 KiB
Swift

//
// MP_DownloadManager.swift
// MusicPlayer
//
// Created by 16 on 2024/5/14.
//
import Foundation
import Foundation
import Alamofire
class DownloadManager: NSObject, URLSessionDownloadDelegate {
static let shared = DownloadManager()
var session: URLSession!
var progressHandlers: [URL: (CGFloat) -> Void] = [:]
var completionHandlers: [URL: (Result<URL, Error>) -> Void] = [:]
var downloadTasks: [URL: URLSessionDownloadTask] = [:]
var progressStorage: [URL: CGFloat] = [:] //
private override init() {
super.init()
let configuration = URLSessionConfiguration.background(withIdentifier: "com.yourApp.backgroundDownload")
session = URLSession(configuration: configuration, delegate: self, delegateQueue: nil)
}
func downloadVideo(from url: URL, videoId: String, progressHandler: @escaping (CGFloat) -> Void, completion: @escaping (Result<URL, Error>) -> Void) {
let downloadTask = session.downloadTask(with: url)
progressHandlers[url] = progressHandler
completionHandlers[url] = completion
downloadTasks[url] = downloadTask
downloadTask.resume()
}
func getProgress(for url: URL) -> CGFloat? {
return progressStorage[url]
}
// URLSessionDownloadDelegate methods
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
guard let originalURL = downloadTask.originalRequest?.url else { return }
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let downloadsURL = documentsURL.appendingPathComponent("Downloads")
if !FileManager.default.fileExists(atPath: downloadsURL.path) {
do {
try FileManager.default.createDirectory(at: downloadsURL, withIntermediateDirectories: true, attributes: nil)
} catch {
completionHandlers[originalURL]?(.failure(error))
return
}
}
let fileURL = downloadsURL.appendingPathComponent("\(MP_PlayerManager.shared.loadPlayer.currentVideo.song.videoId ?? "").mp4")
do {
try FileManager.default.moveItem(at: location, to: fileURL)
completionHandlers[originalURL]?(.success(fileURL))
progressStorage[originalURL] = nil //
} catch {
completionHandlers[originalURL]?(.failure(error))
}
}
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
guard let originalURL = downloadTask.originalRequest?.url else { return }
let progress = CGFloat(totalBytesWritten) / CGFloat(totalBytesExpectedToWrite)
progressHandlers[originalURL]?(progress)
progressStorage[originalURL] = progress //
}
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
guard let originalURL = task.originalRequest?.url else { return }
if let error = error {
completionHandlers[originalURL]?(.failure(error))
}
}
}
//class DownloadManager {
//
// static let shared = DownloadManager()
//
// private init() {}
//
// func downloadVideo(from url: URL, videoId: String, progressView: CircularProgressView, completion: @escaping (Result<URL, Error>) -> Void) {
// let destination: DownloadRequest.Destination = { _, _ in
// let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
// let downloadsURL = documentsURL.appendingPathComponent("Downloads")
//
// // Downloads
// if !FileManager.default.fileExists(atPath: downloadsURL.path) {
// do {
// try FileManager.default.createDirectory(at: downloadsURL, withIntermediateDirectories: true, attributes: nil)
// } catch {
// completion(.failure(error))
// return (downloadsURL, [.removePreviousFile, .createIntermediateDirectories])
// }
// }
//
// let fileURL = downloadsURL.appendingPathComponent("\(videoId).mp4")
// return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
// }
//
// AF.download(url, to: destination).downloadProgress { progress in
// progressView.setProgress(to: CGFloat(progress.fractionCompleted))
// }.response { response in
// if let error = response.error {
// completion(.failure(error))
// } else if let filePath = response.fileURL {
// completion(.success(filePath))
// }
// }
// }
//}