From aa5c132c3bccaf4103c74b95393cd80db79f92f1 Mon Sep 17 00:00:00 2001 From: Nicholas Tay Date: Tue, 15 Mar 2022 17:04:38 +1100 Subject: Make items Decodable and hook up to a JSON dummy endpoint Resources: - https://stackoverflow.com/questions/56443859/display-in-json-api-table-view-in-swift - https://www.avanderlee.com/swift/json-parsing-decoding/ - https://stackoverflow.com/questions/24321165/make-rest-api-call-in-swift --- foray/ForayTableViewController.swift | 74 ++++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 21 deletions(-) diff --git a/foray/ForayTableViewController.swift b/foray/ForayTableViewController.swift index dc32611..a5c367a 100644 --- a/foray/ForayTableViewController.swift +++ b/foray/ForayTableViewController.swift @@ -7,12 +7,12 @@ import UIKit -enum ItemType { +enum ItemType: String, Decodable { case item case quest } -struct MyItem { +struct MyItem: Decodable { var type: ItemType var releaseDate: Date var id: String @@ -47,17 +47,7 @@ class ForayTableViewController: UITableViewController { // MARK: - Static data TEMP - let items = [ - MyItem(type: .item, releaseDate: parseDate("2006-05-26"), id: "mh", name: "Miners Helmet"), - MyItem(type: .item, releaseDate: parseDate("2010-05-01"), id: "it", name: "Inner Tube"), - MyItem(type: .item, releaseDate: parseDate("2009-04-24"), id: "tbg", name: "Toboggan"), - MyItem(type: .item, releaseDate: parseDate("2006-03-29"), id: "spy", name: "Spy Phone"), - MyItem(type: .item, releaseDate: parseDate("2008-11-18"), id: "bnb", name: "Black Ninja Belt"), - MyItem(type: .quest, releaseDate: parseDate("2006-05-23"), id: "cmp", name: "Case of the Missing Puffles"), - MyItem(type: .quest, releaseDate: parseDate("2009-11-16"), id: "gsm", name: "G's Secret Mission"), - MyItem(type: .quest, releaseDate: parseDate("2009-04-18"), id: "cmc", name: "Case of the Missing Coins"), - ] - + var items = [MyItem]() var sections = [YearSection]() // MARK: - On load @@ -65,14 +55,56 @@ class ForayTableViewController: UITableViewController { override func viewDidLoad() { super.viewDidLoad() - let groups = Dictionary(grouping: self.items) { (item) in - return firstDayOfYear(date: item.releaseDate) - } - 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 } + loadApiData(onComplete: { (apiItems) in + self.items = apiItems + + let groups = Dictionary(grouping: self.items) { (item) in + return firstDayOfYear(date: item.releaseDate) + } + 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() + }) + } + + func loadApiData(onComplete: @escaping ([MyItem]) -> ()) { +// return [ +// MyItem(type: .item, releaseDate: parseDate("2006-05-26"), id: "mh", name: "Miners Helmet"), +// MyItem(type: .item, releaseDate: parseDate("2010-05-01"), id: "it", name: "Inner Tube"), +// MyItem(type: .item, releaseDate: parseDate("2009-04-24"), id: "tbg", name: "Toboggan"), +// MyItem(type: .item, releaseDate: parseDate("2006-03-29"), id: "spy", name: "Spy Phone"), +// MyItem(type: .item, releaseDate: parseDate("2008-11-18"), id: "bnb", name: "Black Ninja Belt"), +// MyItem(type: .quest, releaseDate: parseDate("2006-05-23"), id: "cmp", name: "Case of the Missing Puffles"), +// MyItem(type: .quest, releaseDate: parseDate("2009-11-16"), id: "gsm", name: "G's Secret Mission"), +// MyItem(type: .quest, releaseDate: parseDate("2009-04-18"), id: "cmc", name: "Case of the Missing Coins"), +// ] + + var request = URLRequest(url: URL(string: "https://.../dummy.json")!) + let authData = ("..:..").data(using: .utf8)!.base64EncodedString() + request.addValue("Basic \(authData)", forHTTPHeaderField: "Authorization") + + URLSession.shared.dataTask(with: request, completionHandler: { data, response, error -> Void in + print("finished getting data") + print(response!) + + let jsonDecoder = JSONDecoder() + jsonDecoder.dateDecodingStrategy = .custom({ (decoder) -> Date in + let container = try decoder.singleValueContainer() + let dateStr = try container.decode(String.self) + return parseDate(dateStr) + }) + let items = try! jsonDecoder.decode([MyItem].self, from: data!) + print("json decoded") + + // Passing back to UI, need to do it on the main thread (I think due to async?) + DispatchQueue.main.async { + onComplete(items) + } + }).resume() } // MARK: - Table view data source -- cgit