113 lines
4.7 KiB
Swift
113 lines
4.7 KiB
Swift
//
|
||
// MP_DownloadManager.swift
|
||
// MusicPlayer
|
||
//
|
||
// Created by 忆海16 on 2024/5/14.
|
||
//
|
||
|
||
import Foundation
|
||
import Foundation
|
||
import Tiercel
|
||
class MP_DownloadManager: NSObject {
|
||
static let shared = MP_DownloadManager()
|
||
|
||
var session: SessionManager!
|
||
var progressHandlers: [String: (CGFloat) -> Void] = [:]
|
||
var completionHandlers: [URL: (Result<MPPositive_SongItemModel, Error>) -> Void] = [:]
|
||
var downloadTasks: [URL: URLSessionDownloadTask] = [:]
|
||
var progressStorage: [String: CGFloat] = [:] // 新增进度存储
|
||
var songHandlers:[URL: MPPositive_SongItemModel] = [:]
|
||
private override init() {
|
||
super.init()
|
||
var configuration = SessionConfiguration()
|
||
configuration.timeoutIntervalForRequest = 60
|
||
configuration.maxConcurrentTasksLimit = 6
|
||
configuration.allowsCellularAccess = true
|
||
session = SessionManager("com.yourApp.backgroundDownload", configuration: configuration)
|
||
}
|
||
func downloadVideo(from url: URL, song:MPPositive_SongItemModel, progressHandler: @escaping (CGFloat) -> Void, completion: @escaping (Result<MPPositive_SongItemModel, Error>) -> Void) {
|
||
progressHandlers[song.videoId] = progressHandler
|
||
completionHandlers[url] = completion
|
||
songHandlers[url] = song
|
||
let downloadTask = session.download(url, headers: ["Accept-Encoding": "gzip, deflate"])
|
||
//配置进度条
|
||
downloadTask?.progress(handler: { [weak self] (task) in
|
||
guard let self = self else {return}
|
||
progressHandlers[song.videoId]?(task.progress.fractionCompleted)
|
||
progressStorage[song.videoId] = task.progress.fractionCompleted
|
||
})
|
||
//配置任务完成事件
|
||
downloadTask?.success(handler: { [weak self] (task) in
|
||
guard let self = self else {return}
|
||
//任务下载成功,进行文件转移
|
||
let originalURL = task.url
|
||
//任务下载地址
|
||
let filePathUrl:URL = URL(fileURLWithPath: task.filePath)
|
||
print("任务下载地址:\(filePathUrl)")
|
||
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("\(song.videoId ?? "").mp4")
|
||
do {
|
||
try FileManager.default.moveItem(at: filePathUrl, to: fileURL)
|
||
//回调VideoID
|
||
completionHandlers[originalURL]?(.success(songHandlers[originalURL]!))
|
||
progressStorage[song.videoId] = nil // 清除已完成任务的进度记录
|
||
} catch {
|
||
completionHandlers[originalURL]?(.failure(error))
|
||
}
|
||
//移除任务
|
||
if task.status == .succeeded {
|
||
session.remove(task, completely: true) {_ in
|
||
print("\(song.title ?? "")下载任务完成,移除任务")
|
||
}
|
||
}
|
||
}).failure(handler: { [weak self] (task) in
|
||
guard let self = self else {return}
|
||
//任务下载失败
|
||
let originalURL = task.url
|
||
if let error = task.error {
|
||
completionHandlers[originalURL]?(.failure(error))
|
||
}
|
||
if task.status == .failed {
|
||
session.cancel(task) { _ in
|
||
print("\(song.title ?? "")下载任务失败,取消任务")
|
||
}
|
||
}
|
||
})
|
||
}
|
||
func getProgress(for videoId: String) -> CGFloat? {
|
||
return progressStorage[videoId]
|
||
}
|
||
func cancelAllTasksIfNeeded() {
|
||
// 根据需求,取消所有任务,或者根据任务状态进行过滤
|
||
for key in progressStorage.keys {
|
||
session.cancel(key)
|
||
}
|
||
}
|
||
//删除下载文件
|
||
func deleteFileDocuments(_ videoId:String, completion:@escaping((String) -> Void)) {
|
||
let downloadsURL = DocumentsURL.appendingPathComponent("Downloads")
|
||
let fileURL = downloadsURL.appendingPathComponent("\(videoId).mp4")
|
||
if FileManager.default.fileExists(atPath: fileURL.path) {
|
||
do{
|
||
try FileManager.default.removeItem(at: fileURL)
|
||
//文件删除成功
|
||
completion(videoId)
|
||
print("成功删除了\(videoId)文件")
|
||
}catch{
|
||
print("删除文件时发生错误:\(error)")
|
||
}
|
||
}else {
|
||
print("文件不存在")
|
||
}
|
||
}
|
||
}
|