diff options
| author | Nicholas Tay <nick@windblume.net> | 2022-07-17 02:13:04 +1000 | 
|---|---|---|
| committer | Nicholas Tay <nick@windblume.net> | 2022-07-17 02:13:16 +1000 | 
| commit | 1adbed9f8b94521befd237c14d36325a55037a41 (patch) | |
| tree | 91d81b4740514083010c72f5f0559283ccd849fa /foray | |
| parent | daee1f1b5c739f42ba54a1ebbb9655f5034e315f (diff) | |
| download | forayios-1adbed9f8b94521befd237c14d36325a55037a41.tar.gz forayios-1adbed9f8b94521befd237c14d36325a55037a41.tar.bz2 forayios-1adbed9f8b94521befd237c14d36325a55037a41.zip | |
Experiment with async/await
Note that URLSession async only works >=iOS 15. I changed the target for
now, but may mess with continuations.
Diffstat (limited to 'foray')
| -rw-r--r-- | foray/Fetchers/ForayFetcher.swift | 27 | ||||
| -rw-r--r-- | foray/Presenters/PenguinItemPresenter.swift | 19 | ||||
| -rw-r--r-- | foray/Scenes/ForayTableViewController.swift | 16 | 
3 files changed, 31 insertions, 31 deletions
| diff --git a/foray/Fetchers/ForayFetcher.swift b/foray/Fetchers/ForayFetcher.swift index d8df037..e4c6fd9 100644 --- a/foray/Fetchers/ForayFetcher.swift +++ b/foray/Fetchers/ForayFetcher.swift @@ -27,23 +27,18 @@ class ForayFetcher {          return jd      }() -    func fetch<T: Decodable>(url: String, -                             receiver: @escaping (T) -> ()) { -        // Fetch on a background thread -        DispatchQueue.global(qos: .background).async { -            var request = URLRequest(url: URL(string: url)!) -            request.cachePolicy = .reloadRevalidatingCacheData // Needed otherwise default caching policy seems not to check properly -             -            // Basic auth if required -            if (self.basicUsername != nil && self.basicPassword != nil) { -                let authData = (self.basicUsername! + ":" + self.basicPassword!).data(using: .utf8)!.base64EncodedString() -                request.addValue("Basic \(authData)", forHTTPHeaderField: "Authorization") -            } +    func fetch<T: Decodable>(url: String) async throws -> T { +        var request = URLRequest(url: URL(string: url)!) +        request.cachePolicy = .reloadRevalidatingCacheData // Needed otherwise default caching policy seems not to check properly -            URLSession.shared.dataTask(with: request, completionHandler: { data, response, error -> Void in -                let items = try! self.jsonDecoder.decode(T.self, from: data!) -                receiver(items) -            }).resume() +        // Basic auth if required +        if (self.basicUsername != nil && self.basicPassword != nil) { +            let authData = (self.basicUsername! + ":" + self.basicPassword!).data(using: .utf8)!.base64EncodedString() +            request.addValue("Basic \(authData)", forHTTPHeaderField: "Authorization")          } + +        let (data, _) = try await URLSession.shared.data(for: request) +        let items = try jsonDecoder.decode(T.self, from: data) +        return items      }  } diff --git a/foray/Presenters/PenguinItemPresenter.swift b/foray/Presenters/PenguinItemPresenter.swift index c4553ae..1d617bf 100644 --- a/foray/Presenters/PenguinItemPresenter.swift +++ b/foray/Presenters/PenguinItemPresenter.swift @@ -8,18 +8,19 @@  import Foundation  class PenguinItemPresenter { + +    private struct Constants { +        static let apiEndpoint = "https://users.windblume.net/~nick/upload/dummy.json" +    }      let fetcher = ForayFetcher() -    func fetch(receiver: @escaping ([PenguinItemViewModel]) -> ()) { -        fetcher.fetch(url: "https://users.windblume.net/~nick/upload/dummy.json") { [weak self] (apiItems: [PenguinItemModel]) in -            // Callback to main thread here -            // There probably is a nicer way to do it, but we will DispatchQueue it back -            // from the Presenter-level for now (main thread from VC onwards) -            DispatchQueue.main.async { -                guard let self = self else { return } -                receiver(self.transform(models: apiItems)) -            } +    func fetch() async -> [PenguinItemViewModel] { +        do { +            let apiItems: [PenguinItemModel] = try await fetcher.fetch(url: Constants.apiEndpoint) +            return transform(models: apiItems) +        } catch { +            return []          }      } diff --git a/foray/Scenes/ForayTableViewController.swift b/foray/Scenes/ForayTableViewController.swift index a29088c..849553c 100644 --- a/foray/Scenes/ForayTableViewController.swift +++ b/foray/Scenes/ForayTableViewController.swift @@ -42,21 +42,25 @@ class ForayTableViewController: UITableViewController, Coordinated {          self.refreshControl?.addTarget(self, action: #selector(doRefresh), for: UIControl.Event.valueChanged)      } -    @objc func doRefresh(sender: AnyObject) { +    @objc +    func doRefresh(sender: AnyObject) {          reloadApiData()      }      func reloadApiData() { -        presenter.fetch { [weak self] (data: [PenguinItemViewModel]) in -            guard let self = self else { return } -             -            let groups = Dictionary(grouping: data) { $0.year } +        Task(priority: .medium) { [weak self] in +            let models = await self?.presenter.fetch() + +            guard let self = self, +                  let models = models else { return } + +            let groups = Dictionary(grouping: models) { $0.year }              self.sections = groups.map { (key, values) in                  return YearSection(year: key, items: values)              }              // Sort the sections from oldest year to newest              self.sections.sort { (lhs, rhs) in lhs.year < rhs.year } -             +              self.tableView.reloadData()              self.refreshControl?.endRefreshing()              self.coordinator?.hideLoading() | 
