How to download file in swift?
Example downloader class without Alamofire:
class Downloader { class func load(URL: NSURL) { 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) { // Success let statusCode = (response as NSHTTPURLResponse).statusCode println("Success: \(statusCode)") // This is your file-variable: // data } else { // Failure println("Failure: %@", error.localizedDescription); } }) task.resume() }}
This is how to use it in your own code:
class Foo { func bar() { if var URL = NSURL(string: "http://www.mywebsite.com/myfile.pdf") { Downloader.load(URL) } }}
Swift 3 Version
Also note to download large files on disk instead instead in memory. see `downloadTask:
class Downloader { class func load(url: URL, to localUrl: URL, completion: @escaping () -> ()) { let sessionConfig = URLSessionConfiguration.default let session = URLSession(configuration: sessionConfig) let request = try! URLRequest(url: url, method: .get) 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("Success: \(statusCode)") } do { try FileManager.default.copyItem(at: tempLocalUrl, to: localUrl) completion() } catch (let writeError) { print("error writing file \(localUrl) : \(writeError)") } } else { print("Failure: %@", error?.localizedDescription); } } task.resume() }}
Swift 4 and Swift 5 Version if Anyone still needs this
import Foundationclass 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!)")}
Here's an example that shows how to do sync & async.
import Foundationclass 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)") })