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
//下載進(jìn)度回調(diào)
var progressBlock: ((Float) -> ())?
var currentSession:URLSession?
var downloadTask:URLSessionDataTask?
override init() {
super.init()
currentSession = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: OperationQueue.main)
}
//MARK:創(chuàng)建下載
@objc func createDownloadTask() {
//下載地址
let Url = URL(string: self.downUrl)
//請(qǐng)求
var request = URLRequest(url: Url!)
//下載文件大小
totalReceivedContentLength = Float(PublicFunction.fileSizeForPath(path:self.savePath))
print("本地文件大小---\(totalReceivedContentLength)")
//設(shè)置請(qǐng)求頭
if totalReceivedContentLength > 0 {
let contentRange = "bytes=\(PublicFunction.fileSizeForPath(path:self.savePath))-"
print("設(shè)置下載偏移量---\(contentRange)")
request.addValue(contentRange, forHTTPHeaderField: "Range")
}
self.downloadTask = currentSession?.dataTask(with: request)
}
//MARK:啟動(dòng)斷點(diǎn)續(xù)傳下載請(qǐng)求
func start() {
print("下載文件大小---\(totalReceivedContentLength)")
self.downloadTask?.resume()
}
//MARK:取消斷點(diǎn)續(xù)傳下載請(qǐng)求
func cancel() {
self.downloadTask?.suspend()
}
// 當(dāng)用戶確定, 繼續(xù)接受數(shù)據(jù)的時(shí)候調(diào)用
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
//更新進(jìn)度
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()//將節(jié)點(diǎn)跳到文件的末尾
fileHandle?.write(data)//追加寫入數(shù)據(jù)
fileHandle?.closeFile()
//下載進(jìn)度
let proValu:Float = Float(totalReceivedContentLength/totalContentLength)
//print("總文件大小---\(totalReceivedContentLength)---\(totalContentLength)")
if let onProgress = progressBlock {
onProgress(proValu)
}
}
// 請(qǐng)求完成時(shí)候調(diào)用
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
if error == nil {
print("下載完成---\(totalReceivedContentLength)---\(totalContentLength)")
self.downloadTask?.cancel()
}
}
}
//退出,會(huì)先讀取本地文件大小罢洲,跟著之前下載的進(jìn)度
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("初始化創(chuàng)建文件")
FileManager.default.createFile(atPath: savePath, contents: nil, attributes: nil)
}
//更新下載進(jìn)度
downLoadManager.progressBlock = { (progress) in
OperationQueue.main.addOperation {
print("下載進(jìn)度:\(progress)")
}
}
//開始下載
downLoadManager.start()
//暫停下載
downLoadManager.cancel()