Created
August 22, 2018 19:15
-
-
Save nullpixel/6b5b0e546c9ec64596e57811aa9a2f78 to your computer and use it in GitHub Desktop.
A simple and untested file downloader in swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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")") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
😄