How to download the task using URLSessionDownloadDelegate

By passing days the mobile APP is going more UX and UI friendly . Listening uninterrupted music or videos or browsing infifine scroll in a APP that means APP has to download something from the internet, be it images, data or pdf files or whatever. While your app downloads the required resources, your user has to wait. Now, this isn’t an issue if the resources are small or can be fetched really fast. What if the process isn’t fast enough or the resource is very large (say size in MB in double or even triple digits!)? Your users will have to stare at a blank screen with a probably unresponsive app (depending on how you handled resource loading) which is a deal-breaker and may lead users away from your app. You must do something to assure the users that the required resource is indeed loading and the app isn’t stuck at some deadlock. Show them some progress. Animation, text, percentage labels — whatever goes with your app.

A protocol defining methods that URL session instances call on their delegates to handle task-level events specific to download tasks.

in addition to the methods in this protocol, be sure to implement the methods in the URLSessionTaskDelegate and URLSessionDelegate protocols to handle events common to all task types and session-level events, respectively.

func urlSession(URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo: URL)

func urlSession(URLSession, downloadTask: URLSessionDownloadTask, didResumeAtOffset: Int64, expectedTotalBytes: Int64)

func urlSession(URLSession, downloadTask: URLSessionDownloadTask, didWriteData: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64)

func downloadTask(with: URL) -> URLSessionDownloadTask
Creates a download task that retrieves the contents of the specified URL and saves the results to a file.

func downloadTask(with: URL, completionHandler: (URL?, URLResponse?, Error?) -> Void) -> URLSessionDownloadTask

Creates a download task that retrieves the contents of the specified URL, saves the results to a file, and calls a handler upon completion.

class YourDownloadDelegate: YourAPPDelegate, URLSessionDownloadDelegate {

var yourdownloadTask: URLSessionDownloadTask { return task as! URLSessionDownloadTask }

var progress: Progress
var progressHandler: (closure: Request.ProgressHandler, queue: DispatchQueue)?

var resumeData: Data?

override var data: Data? { return resumeData }

var destination: DownloadRequest.DownloadFileDestination?
var tempURL: URL?
var destinationURL: URL?

var fileURL: URL? { return destination != nil ? destinationURL : tempURL }
override init(task: URLSessionTask?) {
progress = Progress(totalUnitCount: 0)
super.init(task: task)
override func reset() {

progress = Progress(totalUnitCount: 0)
resumeData = nil


/ called when Finishing the downloading process

var downloadTaskDidFinishDownloadingToURL: ((URLSession, URLSessionDownloadTask, URL) -> URL)?
// Downloading task written or saving

var downloadTaskDidWriteData: ((URLSession, URLSessionDownloadTask, Int64, Int64, Int64) -> Void)?

var downloadTaskDidResumeAtOffset: ((URLSession, URLSessionDownloadTask, Int64, Int64) -> Void)?
func urlSession(
_ session: URLSession,
downloadTask: URLSessionDownloadTask,
didFinishDownloadingTo location: URL)
tempURL = location

let destination = destination,
let response = downloadTask.response as? HTTPURLResponse
else { return }

let result = destination(location, response)
let destinationURL = result.destinationURL
let options = result.options

self.destinationURL = destinationURL

do {
if options.contains(.removePreviousFile), FileManager.default.fileExists(atPath: destinationURL.path) {
try FileManager.default.removeItem(at: destinationURL)

if options.contains(.createIntermediateDirectories) {
let directory = destinationURL.deletingLastPathComponent()
try FileManager.default.createDirectory(at: directory, withIntermediateDirectories: true)
try FileManager.default.moveItem(at: location, to: destinationURL)
} catch {
self.error = error
func urlSession(
_ session: URLSession,
downloadTask: URLSessionDownloadTask,
didWriteData bytesWritten: Int64,
totalBytesWritten: Int64,
totalBytesExpectedToWrite: Int64)
if initialResponseTime == nil { initialResponseTime = CFAbsoluteTimeGetCurrent() }

// Downloading Task Written

if let downloadTaskDidWriteData = downloadTaskDidWriteData {
} else {
progress.totalUnitCount = totalBytesExpectedToWrite
progress.completedUnitCount = totalBytesWritten

if let progressHandler = progressHandler {
progressHandler.queue.async { progressHandler.closure(self.progress) }
func urlSession(
_ session: URLSession,
downloadTask: URLSessionDownloadTask,
didResumeAtOffset fileOffset: Int64,
expectedTotalBytes: Int64)
if let downloadTaskDidResumeAtOffset = downloadTaskDidResumeAtOffset {
downloadTaskDidResumeAtOffset(session, downloadTask, fileOffset, expectedTotalBytes)
} else {
progress.totalUnitCount = expectedTotalBytes
progress.completedUnitCount = fileOffset