Created
June 13, 2020 13:07
-
-
Save cipolleschi/f3997d09061bd71061622284bf98ca61 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| // Data structure for a Movie | |
| struct Movie: Codable { | |
| let id: String | |
| let title: String | |
| let description: String | |
| let director: String | |
| let producer: String | |
| let releaseDate: String | |
| let rtScore: String | |
| let url: URL | |
| } | |
| // Function that starts the download and updates the UI afterward | |
| func downloadMovies() { | |
| self.promisifyDownload(url: URL(string: "https://ghibliapi.herokuapp.com/films")!) | |
| .then(in: .main) { [weak self] movies in | |
| // download finished. Update the state. | |
| self?.localState.movies = movies.count | |
| } | |
| .catch(in: .main) { [weak self] error in | |
| // download errored, present the alert with the error. | |
| let vc = UIAlertController(title: "Error", message: "Error obtained: \(error.localizedDescription)", preferredStyle: .alert) | |
| vc.addAction(UIAlertAction(title: "Ok", style: .default, handler: nil)) | |
| self.present(vc, animated: true, completion: nil) | |
| } | |
| } | |
| // Function that transform the download in a promise. | |
| func promisifyDownload(url: URL) -> Promise<[Movie]> { | |
| return Promise<[Movie]>(in: .background) { [weak self] resolve, reject, _ in | |
| // data delegate that will resolve or reject the promise. | |
| let dataDelegate = DataDelegate(resolve: resolve, reject: reject) | |
| let session = URLSession(configuration: .default, delegate: dataDelegate, delegateQueue: nil) | |
| let task = session.dataTask(with: url) | |
| // start the download. | |
| task.resume() | |
| } | |
| } | |
| // Delegate for the download of the movies. | |
| class DataDelegate: NSObject, URLSessionDataDelegate { | |
| let resolve: ([Movie]) -> () | |
| let reject: (Error) -> () | |
| init(resolve: @escaping ([Movie]) -> (), reject: @escaping (Error) -> ()) { | |
| self.resolve = resolve | |
| self.reject = reject | |
| } | |
| func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { | |
| do { | |
| // decode the received data | |
| let decoder = JSONDecoder() | |
| decoder.keyDecodingStrategy = .convertFromSnakeCase | |
| let movies = try decoder.decode([Movie].self, from: data) | |
| // resolve the promise so that the ui can be updated. | |
| self.resolve(movies) | |
| } catch { | |
| self.reject(error) | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment