From 07a6eb8325d3b67d998003d3fe5ab34e1a72f106 Mon Sep 17 00:00:00 2001 From: Nicholas Tay Date: Fri, 25 Mar 2022 09:52:06 +1100 Subject: getData -> fetch, try threading, move logic around --- foray/ForayNetworkManager.swift | 33 +++++++++++++++-------------- foray/Presenters/PenguinItemPresenter.swift | 16 ++++++++------ foray/Scenes/ForayTableViewController.swift | 2 +- 3 files changed, 28 insertions(+), 23 deletions(-) (limited to 'foray') diff --git a/foray/ForayNetworkManager.swift b/foray/ForayNetworkManager.swift index ab1e2b5..53e9554 100644 --- a/foray/ForayNetworkManager.swift +++ b/foray/ForayNetworkManager.swift @@ -29,22 +29,23 @@ class ForayNetworkManager { return jd }() - func get(url: String, - onComplete: @escaping ([T]) -> ()) { - 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 (basicUsername != nil && basicPassword != nil) { - let authData = (basicUsername! + ":" + basicPassword!).data(using: .utf8)!.base64EncodedString() - request.addValue("Basic \(authData)", forHTTPHeaderField: "Authorization") - } - - URLSession.shared.dataTask(with: request, completionHandler: { data, response, error -> Void in - let items = try! self.jsonDecoder.decode([T].self, from: data!) + func fetch(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 - // Possibly passing back to UI, need to do it on the main thread (I think due to async?) - DispatchQueue.main.async { onComplete(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") + } + + URLSession.shared.dataTask(with: request, completionHandler: { data, response, error -> Void in + let items = try! self.jsonDecoder.decode(T.self, from: data!) + receiver(items) + }).resume() + } } } diff --git a/foray/Presenters/PenguinItemPresenter.swift b/foray/Presenters/PenguinItemPresenter.swift index 0420825..2f3730f 100644 --- a/foray/Presenters/PenguinItemPresenter.swift +++ b/foray/Presenters/PenguinItemPresenter.swift @@ -8,12 +8,16 @@ import Foundation class PenguinItemPresenter { - func getData(onComplete: @escaping ([PenguinItemViewModel]) -> ()) { - ForayNetworkManager.shared.get( - url: "https://users.windblume.net/~nick/upload/dummy.json", - onComplete: { (apiItems: [PenguinItemModel]) in - onComplete(self.transform(models: apiItems)) - }) + func fetch(receiver: @escaping ([PenguinItemViewModel]) -> ()) { + ForayNetworkManager.shared + .fetch(url: "https://users.windblume.net/~nick/upload/dummy.json") { (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 { + receiver(self.transform(models: apiItems)) + } + } } func transform(models: [PenguinItemModel]) -> [PenguinItemViewModel] { diff --git a/foray/Scenes/ForayTableViewController.swift b/foray/Scenes/ForayTableViewController.swift index ed44139..baa0e6b 100644 --- a/foray/Scenes/ForayTableViewController.swift +++ b/foray/Scenes/ForayTableViewController.swift @@ -45,7 +45,7 @@ class ForayTableViewController: UITableViewController, ForayCoordinated { } func reloadApiData() { - presenter.getData(onComplete: { (data: [PenguinItemViewModel]) in + presenter.fetch(receiver: { (data: [PenguinItemViewModel]) in let groups = Dictionary(grouping: data) { $0.year } self.sections = groups.map { (key, values) in return YearSection(year: key, items: values) -- cgit