apple 官方文档
- 在Library/Caches 的目录下创建 Music 文件夹
let musicPath = NSHomeDirectory() + "/Library/Caches/Music"
do {
try FileManager.default.createDirectory(atPath: musicPath, withIntermediateDirectories: true, attributes: nil)
} catch {
print(error.localizedDescription)
}
简单下载
guard let url = URL(string: "https://audio-ssl.itunes.apple.com/itunes-assets/AudioPreview118/v4/49/3a/a3/493aa3e4-908d-9716-f7d7-cb01c0edbf3d/mzaf_1133582187629104439.plus.aac.p.m4a") else { return }
let fileName = url.lastPathComponent
let savePath = musicPath + "/" + fileName
let downloadTask = URLSession.shared.downloadTask(with: url) { (url, response, error) in
guard let fileURL = url else { return }
do {
try FileManager.default.moveItem(atPath: fileURL.path, toPath: savePath)
} catch {
print("file error: \(error)")
}
}
downloadTask.resume()
获取下载进度 遵循 URLSessionDownloadDelegate 协议
private lazy var urlSession = URLSession(configuration: .default, delegate: self, delegateQueue: nil)
private var downloadTask:URLSessionDownloadTask?
downloadTask = urlSession.downloadTask(with: url)
downloadTask?.resume()
- URLSessionDownloadDelegate
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
do {
try FileManager.default.moveItem(atPath: location.path, toPath: savePath)
print("下载完成")
} catch {
print("file error: \(error)")
}
}
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
if downloadTask == downloadTask {
let totalSize = ByteCountFormatter.string(fromByteCount: totalBytesExpectedToWrite, countStyle: .file)
let downLoadedSize = ByteCountFormatter.string(fromByteCount: totalBytesWritten, countStyle: .file)
let calculatedProgress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
DispatchQueue.main.async {
print("总大小: \(totalSize) , 已下载: \(downLoadedSize), 进度: \(calculatedProgress)")
}
}
}
后台下载
- 遵循 URLSessionDelegate,URLSessionDownloadDelegate
private var resumeData:Data?
private var sessionDownloadTask:URLSessionDownloadTask?
private lazy var urlSession:URLSession = {
let config = URLSessionConfiguration.background(withIdentifier: "MySession")
config.isDiscretionary = true
config.sessionSendsLaunchEvents = true
return URLSession(configuration: config, delegate: self, delegateQueue: nil)
}()
guard let url = URL(string: "https://audio-ssl.itunes.apple.com/itunes-assets/AudioPreview118/v4/49/3a/a3/493aa3e4-908d-9716-f7d7-cb01c0edbf3d/mzaf_1133582187629104439.plus.aac.p.m4a") else { return }
let fileName = url.lastPathComponent
savePath = musicPath + "/" + fileName
sessionDownloadTask = urlSession.downloadTask(with: url)
sessionDownloadTask?.resume()
sessionDownloadTask?.cancel(byProducingResumeData: { (resumeDataOrNil) in
guard let resumeData = resumeDataOrNil else { return }
self.resumeData = resumeData
})
sessionDownloadTask?.cancel()
guard let data = resumeData else { return }
let downloadTask = urlSession.downloadTask(withResumeData: data)
downloadTask.resume()
sessionDownloadTask = downloadTask
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
do {
try FileManager.default.moveItem(atPath: location.path, toPath: savePath)
print("下载完成")
} catch {
print("file error: \(error)")
}
}
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
if downloadTask == downloadTask {
let totalSize = ByteCountFormatter.string(fromByteCount: totalBytesExpectedToWrite, countStyle: .file)
let downLoadedSize = ByteCountFormatter.string(fromByteCount: totalBytesWritten, countStyle: .file)
let calculatedProgress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
DispatchQueue.main.async {
print("总大小: \(totalSize) , 已下载: \(downLoadedSize), 进度: \(calculatedProgress)")
}
}
}
func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
DispatchQueue.main.async {
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate,
let backgroundCompletionHandler = appDelegate.backgroundCompletionHandler else { return }
backgroundCompletionHandler()
}
}
func application(_ application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
backgroundCompletionHandler = completionHandler
}