119 lines
4.8 KiB
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))
|
|
// }
|
|
// }
|
|
// }
|
|
//}
|
|
|