URLSession(三) 断点续传

515 阅读1分钟

文章摘录

  • 断点续传
var task:URLSessionDownloadTask? // 下载任务
var session:URLSession? // 下载session
var resumeData:Data? // 记录暂停时下载的记录文件
  • 开始/继续下载
if resumeData == nil {
    guard let url = URL(string: "http://dldir1.qq.com/qqfile/QQforMac/QQ_V5.5.1.dmg") else { return }
    let request = URLRequest(url: url)
    session = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: nil)
    task = session?.downloadTask(with: request)
} else {
    // 暂停后 恢复下载
    guard let resumeData = resumeData else { return }
    task = session?.downloadTask(withResumeData: resumeData)
}
task?.resume()
  • 暂停下载
// 任务暂停后返回一个data,是一个记录文件,用来在恢复下载时候用来重新生成一个任务,并不是下载的文件数据
task?.cancel(byProducingResumeData: {[weak self](data) in
    self?.resumeData = data
    self?.task = nil
})
  • 取消下载
if task != nil {
    task?.cancel()
    task = nil
}
  • URLSessionDownloadDelegate
// 下载完成
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
    let locationPath = location.path
    let fileName = downloadTask.response?.suggestedFilename ?? ""
    guard locationPath != "", fileName != "" else { return }
    let documentsPath = NSHomeDirectory() + "/Library/Caches/Download"
    let filePath = documentsPath + "/" + fileName
    do {
        if FileManager.default.fileExists(atPath: documentsPath) == false {
            try FileManager.default.createDirectory(atPath: documentsPath, withIntermediateDirectories: true)
        }
        try FileManager.default.moveItem(atPath: locationPath, toPath: filePath)
    } catch let catchError {
        debugPrint("保存出错 = \(catchError.localizedDescription)")
    }
}

// 接收数据
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
    let progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
    debugPrint("下载进度 \(progress)")
}

// 恢复下载
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didResumeAtOffset fileOffset: Int64, expectedTotalBytes: Int64) {
    let downloadedData = Float(fileOffset) / Float(expectedTotalBytes)
    debugPrint("恢复下载 \(downloadedData)")
}