How to Download Files Using URLSessionDownloadTask

In this blog, we are going to confer how to download large files and save partial data even when the app is terminated and also updating the view when is in the background.

Creating an object of URLSession

Create an object of URLSession which you have to config the identifier using URLSessionConfiguration after make isDiscretionary true so that we will enable downloading with performance in the background state.

    private lazy var urlSession: URLSession = {

        let config = URLSessionConfiguration.background(withIdentifier: "\(Bundle.main.bundleIdentifier ?? "").backgrouns")

        config.isDiscretionary = true

        config.sessionSendsLaunchEvents = true

        return URLSession(configuration: config, delegate: self, delegateQueue: nil)


Following that pass URL from which you need to download the using downloadTask method of URL session class

urlSession.downloadTask(with: URL(string: "your url")!)

Then file downloading will start to track the download data likes totalBytesExpectedToWrite, totalBytesWritten from that you can calculate how much data is downloaded with this delegate method

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {




        let progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)

        debugPrint("Progress \("") \(progress)")


Then, when your file is downloaded you can save in directory of your app.

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask,
 didFinishDownloadingTo location: URL) {
 guard let httpResponse = downloadTask.response as? HTTPURLResponse,
 (200...299).contains(httpResponse.statusCode) else {
 print ("server error")
 do {
 let documentsURL = try
 FileManager.default.url(for: .documentDirectory,
 in: .userDomainMask,
 appropriateFor: nil,
 create: false)
 let savedURL = documentsURL.appendingPathComponent(
 "\(randomString(length: 2)).pdf")
 try FileManager.default.moveItem(at: location, to: savedURL)
 } catch {
 print ("file error: \(error)")
 func randomString(length: Int) -> String {
 let letters : NSString = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
 let len = UInt32(letters.length)
 var randomString = ""
 for _ in 0 ..< length {
 let rand = arc4random_uniform(len)
 var nextChar = letters.character(at: Int(rand))
 randomString += NSString(characters: &nextChar, length: 1) as String
 return randomString

Assume user put your application in background mode then handleEventsForBackgroundURLSession method call of the app delegate class

var backgroundCompletionHandler : ( () -> Void )?
 func app (_ app: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: @escaping () -> Void) {
 debugPrint("handleEventsForBackgroundURLSession: \(identifier)")
 backgroundCompletionHandler = completionHandler

& when download is completed in background state then you have to update the view in the main thread

 func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
 DispatchQueue.main.async {
 guard let appDelegate = UIApplication.shared.delegate as? AppDelegate,
 let backgroundCompletionHandler =
 appDelegate.backgroundCompletionHandler else {

Last Update: December 21, 2018  

December 18, 2018   14   Nandini R    Swift Significance    
Total 0 Votes:

Tell us how can we improve this post?

+ = Verify Human or Spambot ?

Leave a Reply

Your email address will not be published. Required fields are marked *