[ios] How to download file in swift?

I just started learning apple swift programming for iOS coming from android. I basically can now read and manipulate swift code and also learned some common classes used in iOS swift programming but still having some confusion with the syntax and everything.

I'm trying to download file. Like, lets just say coming from this URL

var url = "http://www.mywebsite.com/myfile.pdf"

in a button click. Maybe with visual progress too

Through searching here in stackoverflow, I stumbled upon Alamofire. I might try it but I'm not sure if this is the best way for me to do it.

So, I would like to ask how and what are my options (iOS7 and iOS8) in achieving my goal. Also, pros and cons would be awesome!

This question is related to ios swift file download

The answer is


Try This Code only Swift 3.0 First Create NS Object File Copy this code in created File

import UIKit

class Downloader : NSObject, URLSessionDownloadDelegate {

    var url : URL?
    // will be used to do whatever is needed once download is complete
    var obj1 : NSObject?

    init(_ obj1 : NSObject)
    {
        self.obj1 = obj1
    }

    //is called once the download is complete
    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL)
    {
        //copy downloaded data to your documents directory with same names as source file
        let documentsUrl =  FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
        let destinationUrl = documentsUrl!.appendingPathComponent(url!.lastPathComponent)
        let dataFromURL = NSData(contentsOf: location)
        dataFromURL?.write(to: destinationUrl, atomically: true)

        //now it is time to do what is needed to be done after the download
        //obj1!.callWhatIsNeeded()
    }

    //this is to track progress
    private func URLSession(session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64)
    {
    }

    // if there is an error during download this will be called
    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)
    {
        if(error != nil)
        {
            //handle the error
            print("Download completed with error: \(error!.localizedDescription)");
        }
    }

    //method to be called to download
    func download(url: URL)
    {
        self.url = url

        //download identifier can be customized. I used the "ulr.absoluteString"
        let sessionConfig = URLSessionConfiguration.background(withIdentifier: url.absoluteString)
        let session = Foundation.URLSession(configuration: sessionConfig, delegate: self, delegateQueue: nil)
        let task = session.downloadTask(with: url)
        task.resume()
    }}

then Copy Below Code And put code in place of you want to download file

 object = "http://www.mywebsite.com/myfile.pdf"
       let url1 = URL(string: object!)
        Downloader(url1! as NSObject).download(url: url1!)

iOS 13 Swift 5, 5.1

@IBAction func btnDownload(_ sender: Any) {
    
    // file location to save download file
    let destination: DownloadRequest.DownloadFileDestination = { _, _ in
        var documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
        documentsURL.appendPathComponent(statementPDF)
        return (documentsURL, [.removePreviousFile])
    }
    
    // Alamofire to download file
    Alamofire.download("http://pdf_url", to: destination).responseData { response in
        hideLoader()
        switch response.result {
        case .success:
            // write something here
            if response.destinationURL != nil {
                showAlertMessage(titleStr: APPNAME, messageStr: "File Saved in Documents!")
                
            }
        case .failure:
            showAlertMessage(titleStr: APPNAME, messageStr: response.result.error.debugDescription)
        }
    }
}

Please add these permissions to info.plist, so you will able to check the download file in Document Directory

<key>UIFileSharingEnabled</key>
<true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>

After trying a few of the above suggestions without success (Swift versions...) I ended up using the official documentation: https://developer.apple.com/documentation/foundation/url_loading_system/downloading_files_from_websites

let downloadTask = URLSession.shared.downloadTask(with: url) {
    urlOrNil, responseOrNil, errorOrNil in
    // check for and handle errors:
    // * errorOrNil should be nil
    // * responseOrNil should be an HTTPURLResponse with statusCode in 200..<299
    
    guard let fileURL = urlOrNil else { return }
    do {
        let documentsURL = try
            FileManager.default.url(for: .documentDirectory,
                                    in: .userDomainMask,
                                    appropriateFor: nil,
                                    create: false)
        let savedURL = documentsURL.appendingPathComponent(fileURL.lastPathComponent)
        try FileManager.default.moveItem(at: fileURL, to: savedURL)
    } catch {
        print ("file error: \(error)")
    }
}
downloadTask.resume()

You can also use a third party library that makes life easy, like Just

Just.get("http://www.mywebsite.com/myfile.pdf")

More awesome Swift stuff here https://github.com/matteocrippa/awesome-swift


Use URLSessionDownloadTask to download files in background so that they can completed even if the app is terminated.

For more information see:

https://www.ralfebert.de/snippets/ios/urlsession-background-downloads/

It also shows how to implement progress monitoring for multiple tasks running in parallel:


Yes you can very easily downloads Files from the remote Url Using this code. This Code is working Fine for Me.

func DownlondFromUrl(){
   // Create destination URL 
let documentsUrl:URL =  FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first as URL!
let destinationFileUrl = documentsUrl.appendingPathComponent("downloadedFile.jpg")

//Create URL to the source file you want to download
let fileURL = URL(string: "https://s3.amazonaws.com/learn-swift/IMG_0001.JPG")

let sessionConfig = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfig)

let request = URLRequest(url:fileURL!)

let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
    if let tempLocalUrl = tempLocalUrl, error == nil {
        // Success
        if let statusCode = (response as? HTTPURLResponse)?.statusCode {
            print("Successfully downloaded. Status code: \(statusCode)")
        }

        do {
            try FileManager.default.copyItem(at: tempLocalUrl, to: destinationFileUrl)
        } catch (let writeError) {
            print("Error creating a file \(destinationFileUrl) : \(writeError)")
        }

    } else {
        print("Error took place while downloading a file. Error description: %@", error?.localizedDescription);
    }
}
task.resume()
}

Devran's and djunod's solutions are working as long as your application is in the foreground. If you switch to another application during the download, it fails. My file sizes are around 10 MB and it takes sometime to download. So I need my download function works even when the app goes into background.

Please note that I switched ON the "Background Modes / Background Fetch" at "Capabilities".

Since completionhandler was not supported the solution is not encapsulated. Sorry about that.

--Swift 2.3--

import Foundation 
class Downloader : NSObject, NSURLSessionDownloadDelegate
{
    var url : NSURL? 
    // will be used to do whatever is needed once download is complete
    var yourOwnObject : NSObject?

    init(yourOwnObject : NSObject)
    {
        self.yourOwnObject = yourOwnObject
    }

    //is called once the download is complete
    func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL)
    {
        //copy downloaded data to your documents directory with same names as source file
        let documentsUrl =  NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first
        let destinationUrl = documentsUrl!.URLByAppendingPathComponent(url!.lastPathComponent!)
        let dataFromURL = NSData(contentsOfURL: location)
        dataFromURL?.writeToURL(destinationUrl, atomically: true)

        //now it is time to do what is needed to be done after the download
        yourOwnObject!.callWhatIsNeeded()
    }

    //this is to track progress
    func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64)
    {
    }

    // if there is an error during download this will be called
    func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?)
    {
        if(error != nil)
        {
            //handle the error
            print("Download completed with error: \(error!.localizedDescription)");
        }
    }

    //method to be called to download
    func download(url: NSURL)
    {
        self.url = url

        //download identifier can be customized. I used the "ulr.absoluteString"
        let sessionConfig = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier(url.absoluteString)
        let session = NSURLSession(configuration: sessionConfig, delegate: self, delegateQueue: nil)
        let task = session.downloadTaskWithURL(url)
        task.resume()
    }
}

And here is how to call in --Swift 2.3--

    let url = NSURL(string: "http://company.com/file.txt")
    Downloader(yourOwnObject).download(url!)

--Swift 3--

class Downloader : NSObject, URLSessionDownloadDelegate {

var url : URL?
// will be used to do whatever is needed once download is complete
var yourOwnObject : NSObject?

init(_ yourOwnObject : NSObject)
{
    self.yourOwnObject = yourOwnObject
}

//is called once the download is complete
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL)
{
    //copy downloaded data to your documents directory with same names as source file
    let documentsUrl =  FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
    let destinationUrl = documentsUrl!.appendingPathComponent(url!.lastPathComponent)
    let dataFromURL = NSData(contentsOf: location)
    dataFromURL?.write(to: destinationUrl, atomically: true)

    //now it is time to do what is needed to be done after the download
    yourOwnObject!.callWhatIsNeeded()
}

//this is to track progress
private func URLSession(session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64)
{
}

// if there is an error during download this will be called
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)
{
    if(error != nil)
    {
        //handle the error
        print("Download completed with error: \(error!.localizedDescription)");
    }
}

//method to be called to download
func download(url: URL)
{
    self.url = url

    //download identifier can be customized. I used the "ulr.absoluteString"
    let sessionConfig = URLSessionConfiguration.background(withIdentifier: url.absoluteString)
    let session = Foundation.URLSession(configuration: sessionConfig, delegate: self, delegateQueue: nil)
    let task = session.downloadTask(with: url)
    task.resume()
}}

And here is how to call in --Swift 3--

    let url = URL(string: "http://company.com/file.txt")
    Downloader(yourOwnObject).download(url!)

Here's an example that shows how to do sync & async.

import Foundation

class HttpDownloader {

    class func loadFileSync(url: NSURL, completion:(path:String, error:NSError!) -> Void) {
        let documentsUrl =  NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first as! NSURL
        let destinationUrl = documentsUrl.URLByAppendingPathComponent(url.lastPathComponent!)
        if NSFileManager().fileExistsAtPath(destinationUrl.path!) {
            println("file already exists [\(destinationUrl.path!)]")
            completion(path: destinationUrl.path!, error:nil)
        } else if let dataFromURL = NSData(contentsOfURL: url){
            if dataFromURL.writeToURL(destinationUrl, atomically: true) {
                println("file saved [\(destinationUrl.path!)]")
                completion(path: destinationUrl.path!, error:nil)
            } else {
                println("error saving file")
                let error = NSError(domain:"Error saving file", code:1001, userInfo:nil)
                completion(path: destinationUrl.path!, error:error)
            }
        } else {
            let error = NSError(domain:"Error downloading file", code:1002, userInfo:nil)
            completion(path: destinationUrl.path!, error:error)
        }
    }

    class func loadFileAsync(url: NSURL, completion:(path:String, error:NSError!) -> Void) {
        let documentsUrl =  NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first as! NSURL
        let destinationUrl = documentsUrl.URLByAppendingPathComponent(url.lastPathComponent!)
        if NSFileManager().fileExistsAtPath(destinationUrl.path!) {
            println("file already exists [\(destinationUrl.path!)]")
            completion(path: destinationUrl.path!, error:nil)
        } else {
            let sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration()
            let session = NSURLSession(configuration: sessionConfig, delegate: nil, delegateQueue: nil)
            let request = NSMutableURLRequest(URL: url)
            request.HTTPMethod = "GET"
            let task = session.dataTaskWithRequest(request, completionHandler: { (data: NSData!, response: NSURLResponse!, error: NSError!) -> Void in
                if (error == nil) {
                    if let response = response as? NSHTTPURLResponse {
                        println("response=\(response)")
                        if response.statusCode == 200 {
                            if data.writeToURL(destinationUrl, atomically: true) {
                                println("file saved [\(destinationUrl.path!)]")
                                completion(path: destinationUrl.path!, error:error)
                            } else {
                                println("error saving file")
                                let error = NSError(domain:"Error saving file", code:1001, userInfo:nil)
                                completion(path: destinationUrl.path!, error:error)
                            }
                        }
                    }
                }
                else {
                    println("Failure: \(error.localizedDescription)");
                    completion(path: destinationUrl.path!, error:error)
                }
            })
            task.resume()
        }
    }
}

Here's how to use it in your code:

let url = NSURL(string: "http://www.mywebsite.com/myfile.pdf") 
HttpDownloader.loadFileAsync(url, completion:{(path:String, error:NSError!) in
                println("pdf downloaded to: \(path)")
            })

Swift 3

class ViewController: UIViewController {
    var urlLink: URL!
    var defaultSession: URLSession!
    var downloadTask: URLSessionDownloadTask!
}

// MARK: Button Pressed
    @IBAction func btnDownloadPressed(_ sender: UIButton) {
        let urlLink1 = URL.init(string: "https://github.com/VivekVithlani/QRCodeReader/archive/master.zip")
        startDownloading(url: urlLink!)
}
    @IBAction func btnResumePressed(_ sender: UIButton) {
    downloadTask.resume()
}

@IBAction func btnStopPressed(_ sender: UIButton) {
    downloadTask.cancel()
}

@IBAction func btnPausePressed(_ sender: UIButton) {
    downloadTask.suspend()
}

    func startDownloading (url:URL) {
        let backgroundSessionConfiguration = URLSessionConfiguration.background(withIdentifier: "backgroundSession")
        defaultSession = Foundation.URLSession(configuration: backgroundSessionConfiguration, delegate: self, delegateQueue: OperationQueue.main)
        downloadProgress.setProgress(0.0, animated: false)
        downloadTask = defaultSession.downloadTask(with: urlLink)
        downloadTask.resume()
    }

// MARK:- URLSessionDownloadDelegate
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
    print("File download succesfully")
}

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
    downloadProgress.setProgress(Float(totalBytesWritten)/Float(totalBytesExpectedToWrite), animated: true)
}

func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
    downloadTask = nil
    downloadProgress.setProgress(0.0, animated: true)
    if (error != nil) {
        print("didCompleteWithError \(error?.localizedDescription)")
    }
    else {
        print("The task finished successfully")
    }
}

Here is the Swift 4 version:

static func loadFileAsync(url: URL, completion: @escaping (String?, Error?) -> Void)
{
    let documentsUrl =  FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!

    let destinationUrl = documentsUrl.appendingPathComponent(url.lastPathComponent)

    if FileManager().fileExists(atPath: destinationUrl.path)
    {
        completion(destinationUrl.path, nil)
    }
    else
    {
        let session = URLSession(configuration: URLSessionConfiguration.default, delegate: nil, delegateQueue: nil)
        var request = URLRequest(url: url)
        request.httpMethod = "GET"
        let task = session.dataTask(with: request, completionHandler:
        {
            data, response, error in
            if error == nil
            {
                if let response = response as? HTTPURLResponse
                {
                    if response.statusCode == 200
                    {
                        if let data = data
                        {
                            if let _ = try? data.write(to: destinationUrl, options: Data.WritingOptions.atomic)
                            {
                                completion(destinationUrl.path, error)
                            }
                            else
                            {
                                completion(destinationUrl.path, error)
                            }
                        }
                        else
                        {
                            completion(destinationUrl.path, error)
                        }
                    }
                }
            }
            else
            {
                completion(destinationUrl.path, error)
            }
        })
        task.resume()
    }
}

Swift 4 and Swift 5 Version if Anyone still needs this

import Foundation

class FileDownloader {

    static func loadFileSync(url: URL, completion: @escaping (String?, Error?) -> Void)
    {
        let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!

        let destinationUrl = documentsUrl.appendingPathComponent(url.lastPathComponent)

        if FileManager().fileExists(atPath: destinationUrl.path)
        {
            print("File already exists [\(destinationUrl.path)]")
            completion(destinationUrl.path, nil)
        }
        else if let dataFromURL = NSData(contentsOf: url)
        {
            if dataFromURL.write(to: destinationUrl, atomically: true)
            {
                print("file saved [\(destinationUrl.path)]")
                completion(destinationUrl.path, nil)
            }
            else
            {
                print("error saving file")
                let error = NSError(domain:"Error saving file", code:1001, userInfo:nil)
                completion(destinationUrl.path, error)
            }
        }
        else
        {
            let error = NSError(domain:"Error downloading file", code:1002, userInfo:nil)
            completion(destinationUrl.path, error)
        }
    }

    static func loadFileAsync(url: URL, completion: @escaping (String?, Error?) -> Void)
    {
        let documentsUrl =  FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!

        let destinationUrl = documentsUrl.appendingPathComponent(url.lastPathComponent)

        if FileManager().fileExists(atPath: destinationUrl.path)
        {
            print("File already exists [\(destinationUrl.path)]")
            completion(destinationUrl.path, nil)
        }
        else
        {
            let session = URLSession(configuration: URLSessionConfiguration.default, delegate: nil, delegateQueue: nil)
            var request = URLRequest(url: url)
            request.httpMethod = "GET"
            let task = session.dataTask(with: request, completionHandler:
            {
                data, response, error in
                if error == nil
                {
                    if let response = response as? HTTPURLResponse
                    {
                        if response.statusCode == 200
                        {
                            if let data = data
                            {
                                if let _ = try? data.write(to: destinationUrl, options: Data.WritingOptions.atomic)
                                {
                                    completion(destinationUrl.path, error)
                                }
                                else
                                {
                                    completion(destinationUrl.path, error)
                                }
                            }
                            else
                            {
                                completion(destinationUrl.path, error)
                            }
                        }
                    }
                }
                else
                {
                    completion(destinationUrl.path, error)
                }
            })
            task.resume()
        }
    }
}

Here is how to call this method :-

let url = URL(string: "http://www.filedownloader.com/mydemofile.pdf")
FileDownloader.loadFileAsync(url: url!) { (path, error) in
    print("PDF File downloaded to : \(path!)")
}

Swift 3

you want to download file bite by bite and show in progress view so you want to try this code

import UIKit

class ViewController: UIViewController,URLSessionDownloadDelegate,UIDocumentInteractionControllerDelegate {

    @IBOutlet weak var img: UIImageView!
    @IBOutlet weak var btndown: UIButton!
    var urlLink: URL!
    var defaultSession: URLSession!
    var downloadTask: URLSessionDownloadTask!
    //var backgroundSession: URLSession!
    @IBOutlet weak var progress: UIProgressView!
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view, typically from a nib.

        let backgroundSessionConfiguration = URLSessionConfiguration.background(withIdentifier: "backgroundSession")
        defaultSession = Foundation.URLSession(configuration: backgroundSessionConfiguration, delegate: self, delegateQueue: OperationQueue.main)
        progress.setProgress(0.0, animated: false)
    }

    func startDownloading () {
        let url = URL(string: "http://publications.gbdirect.co.uk/c_book/thecbook.pdf")!
        downloadTask = defaultSession.downloadTask(with: url)
        downloadTask.resume()
    }

    @IBAction func btndown(_ sender: UIButton) {

        startDownloading()

    }

    func showFileWithPath(path: String){
        let isFileFound:Bool? = FileManager.default.fileExists(atPath: path)
        if isFileFound == true{
            let viewer = UIDocumentInteractionController(url: URL(fileURLWithPath: path))
            viewer.delegate = self
            viewer.presentPreview(animated: true)
        }

    }


    // MARK:- URLSessionDownloadDelegate
    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {

        print(downloadTask)
        print("File download succesfully")

        let path = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
        let documentDirectoryPath:String = path[0]
        let fileManager = FileManager()
        let destinationURLForFile = URL(fileURLWithPath: documentDirectoryPath.appendingFormat("/file.pdf"))

        if fileManager.fileExists(atPath: destinationURLForFile.path){
            showFileWithPath(path: destinationURLForFile.path)
            print(destinationURLForFile.path)
        }
        else{
            do {
                try fileManager.moveItem(at: location, to: destinationURLForFile)
                // show file
                showFileWithPath(path: destinationURLForFile.path)
            }catch{
                print("An error occurred while moving file to destination url")
            }
        }



    }

    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
        progress.setProgress(Float(totalBytesWritten)/Float(totalBytesExpectedToWrite), animated: true)
    }

    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        downloadTask = nil
        progress.setProgress(0.0, animated: true)
        if (error != nil) {
            print("didCompleteWithError \(error?.localizedDescription ?? "no value")")
        }
        else {
            print("The task finished successfully")
        }
    }

    func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController
    {
        return self
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

use of this code you want to download file store automatically in Document Directory in your application

this code 100% Working


Downloading a file in Swift 5 with progress reporting, encapsulated into a copy-paste friendly protocol-accessed class:

protocol FileDownloadingDelegate: class {
    func updateDownloadProgressWith(progress: Float)
    func downloadFinished(localFilePath: URL)
    func downloadFailed(withError error: Error)
}

class FilesDownloader: NSObject, URLSessionDownloadDelegate {
    private weak var delegate: FileDownloadingDelegate?

    func download(from url: URL, delegate: FileDownloadingDelegate) {
        self.delegate = delegate
        let sessionConfig = URLSessionConfiguration.background(withIdentifier: url.absoluteString) // use this identifier to resume download after app restart
        let session = Foundation.URLSession(configuration: sessionConfig, delegate: self, delegateQueue: nil)
        let task = session.downloadTask(with: url)
        task.resume()
    }

    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
        DispatchQueue.main.async { self.delegate?.downloadFinished(localFilePath: location) }
    }

    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
        DispatchQueue.main.async { self.delegate?.updateDownloadProgressWith(progress: Float(totalBytesWritten)/Float(totalBytesExpectedToWrite)) }
    }

    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        guard let theError = error else { assertionFailure("something weird happened here"); return }
        DispatchQueue.main.async { self.delegate?.downloadFailed(withError: theError) }
    }

}

How to use it:

class MyViewController: UIViewController {

    private lazy var downloader = FilesDownloader()

    func downloadFile(from url: URL) {
        downloader.download(from: url, delegate: self)
    }

}

extension MyViewController: FileDownloadingDelegate {
    func updateDownloadProgressWith(progress: Float) {
        // self.downloadProgressView.setProgress(progress, animated: true)
    }

    func downloadFinished(tempFilePath: URL) {
        print("downloaded to \(tempFilePath)")
        // resave the file into your desired place using 
        // let dataFromURL = NSData(contentsOf: location)
        // dataFromURL?.write(to: yourDesiredFileUrl, atomically: true)
    }

    func downloadFailed(withError error: Error) {
        // handle the error
    }
}

A simple, robust and elegant download manager supporting simultaneous downloads with closure syntax for progress and completion tracking. Written in Swift with Here

And Use like it

func downloadGIF(url: String) {
    let filename = url
    let range: Range<String.Index> = filename.range(of:"media/")!
    let lastrange: Range<String.Index> = filename.range(of:"/200w_d")!
    let finalPath = String(filename[range.lowerBound..<lastrange.lowerBound])
    filename[range.lowerBound..<lastrange.lowerBound]
    let replaceFirstWords = finalPath.replace(string: "media/", replacement: "SocialStatus_GIF_")
    let destinationUrl = "\(replaceFirstWords).gif"

    let request = URLRequest(url: URL(string: imageData.bg_image)!)
    viewProgress.isHidden = false
    self.btnDownload.isHidden = true
    setSharingButtonFalse()
    let downloadKey = self.downloadManager.downloadFile(withRequest: request,
                                                        withName: destinationUrl,
                                                        shouldDownloadInBackground: true,
                                                        onProgress:  { [weak self] (progress) in
                                                            self?.viewProgress.progress = CGFloat(progress)
                                                            let val = progress * 100
                                                            print("val 1 == \(val)")
                                                            DispatchQueue.main.async {
                                                                self?.viewProgress.setProgressText("\(Int(val))")
                                                            }

    }) { [weak self] (error, url) in
        if let error = error {
            print("Error = \(error as NSError)")
            self!.isDownloaded = false
            self!.viewProgress.isHidden = true
            self!.setSharingButtonTrue()
            self?.viewProgress.setProgressText("\(0)")
            print("handle error since couldn't save GIF")
        } else {
            if let url = url {
                self!.isDownloaded = true
                self!.saveGIFDownloaded()
                self!.viewProgress.isHidden = true
                self!.setSharingButtonTrue()
                self!.createAlbum()
                self!.saveGIF(url: url.absoluteURL)

            }
        }
    }

}

If you need to download only text file into String you can use this simple way, Swift 5:

let list = try? String(contentsOf: URL(string: "https://example.com/file.txt")!)

In case you want non optional result or error handling:

do {
    let list = try String(contentsOf: URL(string: "https://example.com/file.txt")!)
}
catch {
    // Handle error here
}

You should know that network operations may take some time, to prevent it from running in main thread and locking your UI, you may want to execute the code asynchronously, for example:

DispatchQueue.global().async {
    let list = try? String(contentsOf: URL(string: "https://example.com/file.txt")!)
}

Background session (URLSessionDownloadTask, URLSessionUploadTask) allows you to download/upload/cache files in background mode even if app was terminated. In this case when task is done iOS wakes up it (in background) and allows make some competition block in a limited time frame. It is a part of background-transfers approach. It works because the downloading task is executed on nsurlsessiond daemon process[About]

[Background tasks]


Examples related to ios

Adding a UISegmentedControl to UITableView Crop image to specified size and picture location Undefined Symbols error when integrating Apptentive iOS SDK via Cocoapods Keep placeholder text in UITextField on input in IOS Accessing AppDelegate from framework? Autoresize View When SubViews are Added Warp \ bend effect on a UIView? Speech input for visually impaired users without the need to tap the screen make UITableViewCell selectable only while editing Xcode 12, building for iOS Simulator, but linking in object file built for iOS, for architecture arm64

Examples related to swift

Make a VStack fill the width of the screen in SwiftUI Xcode 10.2.1 Command PhaseScriptExecution failed with a nonzero exit code Command CompileSwift failed with a nonzero exit code in Xcode 10 Convert Json string to Json object in Swift 4 iOS Swift - Get the Current Local Time and Date Timestamp Xcode 9 Swift Language Version (SWIFT_VERSION) How do I use Safe Area Layout programmatically? How can I use String substring in Swift 4? 'substring(to:)' is deprecated: Please use String slicing subscript with a 'partial range from' operator Safe Area of Xcode 9 The use of Swift 3 @objc inference in Swift 4 mode is deprecated?

Examples related to file

Gradle - Move a folder from ABC to XYZ Difference between opening a file in binary vs text Angular: How to download a file from HttpClient? Python error message io.UnsupportedOperation: not readable java.io.FileNotFoundException: class path resource cannot be opened because it does not exist Writing JSON object to a JSON file with fs.writeFileSync How to read/write files in .Net Core? How to write to a CSV line by line? Writing a dictionary to a text file? What are the pros and cons of parquet format compared to other formats?

Examples related to download

how to download file in react js How do I download a file with Angular2 or greater Unknown URL content://downloads/my_downloads python save image from url How to download a file using a Java REST service and a data stream How to download file in swift? Where can I download Eclipse Android bundle? How to download image from url android download pdf from url then open it with a pdf reader Flask Download a File