import UIKit
import Foundation
class PublicFunction: NSObject {
//MARK:获取文件大小
static func fileSizeForPath(path:String) -> UInt64 {
var fileSize : UInt64 = 0
do {
let attr = try FileManager.default.attributesOfItem(atPath: path)
fileSize = attr[FileAttributeKey.size] as! UInt64
let dict = attr as NSDictionary
fileSize = dict.fileSize()
} catch {
print("Error: \(error)")
}
return fileSize
}
//MARK:document文档目录
static func documentPath() -> String {
let documentPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first! as String
return documentPath
}
//MARK:下载文件路径
static func downloadDirectory(path:String) -> String {
let downloadFile = PublicFunction.documentPath() + "/\(path)/"
let fileManager = FileManager.default
if fileManager.fileExists(atPath: downloadFile) == false {
do {
try fileManager.createDirectory(atPath: downloadFile, withIntermediateDirectories: true, attributes: nil)
} catch {
print(error)
}
}
return downloadFile
}
}
import UIKit
class DownDataTaskTool: NSObject, URLSessionTaskDelegate, URLSessionDataDelegate {
//文件资源地址
var downUrl:String = ""
//保存路径
var savePath:String = ""
//文件总大小
var totalContentLength:Float = 0
//已下载大小
var totalReceivedContentLength:Float = 0
//下载进度回调
var progressBlock: ((Float) -> ())?
var currentSession:URLSession?
var downloadTask:URLSessionDataTask?
override init() {
super.init()
currentSession = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: OperationQueue.main)
}
//MARK:创建下载
@objc func createDownloadTask() {
//下载地址
let Url = URL(string: self.downUrl)
//请求
var request = URLRequest(url: Url!)
//下载文件大小
totalReceivedContentLength = Float(PublicFunction.fileSizeForPath(path:self.savePath))
print("本地文件大小---\(totalReceivedContentLength)")
//设置请求头
if totalReceivedContentLength > 0 {
let contentRange = "bytes=\(PublicFunction.fileSizeForPath(path:self.savePath))-"
print("设置下载偏移量---\(contentRange)")
request.addValue(contentRange, forHTTPHeaderField: "Range")
}
self.downloadTask = currentSession?.dataTask(with: request)
}
//MARK:启动断点续传下载请求
func start() {
print("下载文件大小---\(totalReceivedContentLength)")
self.downloadTask?.resume()
}
//MARK:取消断点续传下载请求
func cancel() {
self.downloadTask?.suspend()
}
// 当用户确定, 继续接受数据的时候调用
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
//更新进度
totalReceivedContentLength += Float(data.count)
let response:HTTPURLResponse = dataTask.response as! HTTPURLResponse
if response.statusCode == 200 {
totalContentLength = Float(dataTask.countOfBytesExpectedToReceive)
} else if (response.statusCode == 206) {
let contentRange:String = response.allHeaderFields["content-range"] as! String
if contentRange.hasPrefix("bytes") {
let bytes:Array = contentRange.components(separatedBy: CharacterSet.init(charactersIn: " -/"))
if bytes.count == 4 {
totalContentLength = Float(bytes[3])!
}
}
} else {
print("statusCode---\(response.statusCode)")
}
//保存文件
let fileHandle = FileHandle.init(forUpdatingAtPath: self.savePath)
fileHandle?.seekToEndOfFile()//将节点跳到文件的末尾
fileHandle?.write(data)//追加写入数据
fileHandle?.closeFile()
//下载进度
let proValu:Float = Float(totalReceivedContentLength/totalContentLength)
//print("总文件大小---\(totalReceivedContentLength)---\(totalContentLength)")
if let onProgress = progressBlock {
onProgress(proValu)
}
}
// 请求完成时候调用
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
if error == nil {
print("下载完成---\(totalReceivedContentLength)---\(totalContentLength)")
self.downloadTask?.cancel()
}
}
}
//退出,会先读取本地文件大小,跟着之前下载的进度
let downLoadManager = DownDataTaskTool()
downLoadManager.downUrl = "https://webfs.ali.kugou.com/202108021358/f8e446476833e4c950f58d07762c4827/KGTX/CLTX001/84ea1667187279849794a9cc96fa0d27.mp3"
let savePath = PublicFunction.downloadDirectory(path: "download") + "222.mp3"
downLoadManager.savePath = savePath
downLoadManager.createDownloadTask()
if !FileManager.default.fileExists(atPath: savePath) {
print("初始化创建文件")
FileManager.default.createFile(atPath: savePath, contents: nil, attributes: nil)
}
//更新下载进度
downLoadManager.progressBlock = { (progress) in
OperationQueue.main.addOperation {
print("下载进度:\(progress)")
}
}
//开始下载
downLoadManager.start()
//暂停下载
downLoadManager.cancel()