Skip to content

Instantly share code, notes, and snippets.

@nullpixel
Created August 22, 2018 19:15
Show Gist options
  • Save nullpixel/6b5b0e546c9ec64596e57811aa9a2f78 to your computer and use it in GitHub Desktop.
Save nullpixel/6b5b0e546c9ec64596e57811aa9a2f78 to your computer and use it in GitHub Desktop.
A simple and untested file downloader in swift
import Foundation
class FileDownloader {
// MARK: - Properties
private var outputFolder: URL
private var queueIdentifier: String
private var urlSession: URLSession
// MARK: - Types
enum Status {
case completed, inProgress, failed
}
enum Result<Value> {
case success(Value)
case failure(Error?)
}
// MARK: - Initialisers
/**
Creates an instance of a file downloader
*/
init(outputFolder: URL, queueIdentifier: String = "uk.nullpixel.filedownloader.queue") throws {
self.outputFolder = outputFolder
self.queueIdentifier = queueIdentifier
self.urlSession = URLSession(configuration: .background(withIdentifier: queueIdentifier))
try createOutputFolder()
}
// MARK: - Functions
private func createOutputFolder() throws {
try FileManager.default.createDirectory(at: outputFolder, withIntermediateDirectories: true, attributes: nil)
}
/**
Downloads a file from the URL to the output folder as the specified filename.
The completion handler is a result enum, with the success case storing the url of the saved file.
*/
func downloadFile(from fileURL: URL, as fileName: String, onCompletion completionHandler: @escaping(Result<URL>) -> Void) {
urlSession.downloadTask(with: fileURL) { (tempLocation, response, error) in
guard error != nil else {
return completionHandler(.failure(error))
}
guard let response = response as? HTTPURLResponse,
(200...299).contains(response.statusCode),
let tempLocation = tempLocation else {
return completionHandler(.failure(nil))
}
let savedURL = self.outputFolder.appendingPathComponent(fileName)
do {
try FileManager.default.moveItem(at: tempLocation, to: savedURL)
} catch { return completionHandler(.failure(nil)) }
return completionHandler(.success(savedURL))
}.resume()
}
}
// Poor exmaple
let fileDownloader = try! FileDownloader(outputFolder: URL(string: "/dev/null")!)
fileDownloader.downloadFile(from: URL(string: "/dev/null")!, as: "someFile") { result in
switch result {
case .success(let fileURL): print("Downloaded file to \(fileURL)")
case .failure(let error): print("Failed to download file with error \(error?.localizedDescription ?? "No error")")
}
}
@EricRabil
Copy link

😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment