aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--foray.xcodeproj/project.pbxproj8
-rw-r--r--foray/ForayItems.swift25
-rw-r--r--foray/ForayNetworkManager.swift50
-rw-r--r--foray/ForayTableViewController.swift83
4 files changed, 100 insertions, 66 deletions
diff --git a/foray.xcodeproj/project.pbxproj b/foray.xcodeproj/project.pbxproj
index 6c2e2c4..9a09c0f 100644
--- a/foray.xcodeproj/project.pbxproj
+++ b/foray.xcodeproj/project.pbxproj
@@ -7,6 +7,8 @@
objects = {
/* Begin PBXBuildFile section */
+ C011E4F127E6211400C248D6 /* ForayNetworkManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C011E4F027E6211400C248D6 /* ForayNetworkManager.swift */; };
+ C011E4F327E6216C00C248D6 /* ForayItems.swift in Sources */ = {isa = PBXBuildFile; fileRef = C011E4F227E6216C00C248D6 /* ForayItems.swift */; };
C04B45A427DEF117001451A3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C04B45A327DEF117001451A3 /* AppDelegate.swift */; };
C04B45A627DEF117001451A3 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = C04B45A527DEF117001451A3 /* SceneDelegate.swift */; };
C04B45AD27DEF118001451A3 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C04B45AC27DEF118001451A3 /* Assets.xcassets */; };
@@ -17,6 +19,8 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
+ C011E4F027E6211400C248D6 /* ForayNetworkManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForayNetworkManager.swift; sourceTree = "<group>"; };
+ C011E4F227E6216C00C248D6 /* ForayItems.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ForayItems.swift; sourceTree = "<group>"; };
C04B45A027DEF117001451A3 /* foray.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = foray.app; sourceTree = BUILT_PRODUCTS_DIR; };
C04B45A327DEF117001451A3 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
C04B45A527DEF117001451A3 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
@@ -62,7 +66,9 @@
C04B45A527DEF117001451A3 /* SceneDelegate.swift */,
C0FEAF5E27E14C52000A7648 /* ForayDetailViewController.swift */,
C04B45B727DEF2ED001451A3 /* ForayTableViewController.swift */,
+ C011E4F227E6216C00C248D6 /* ForayItems.swift */,
C04EDE4327E4298D00D83005 /* ForayNewTableViewCell.swift */,
+ C011E4F027E6211400C248D6 /* ForayNetworkManager.swift */,
C04B45AC27DEF118001451A3 /* Assets.xcassets */,
C04B45B127DEF118001451A3 /* Info.plist */,
);
@@ -144,10 +150,12 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
+ C011E4F127E6211400C248D6 /* ForayNetworkManager.swift in Sources */,
C04B45B827DEF2ED001451A3 /* ForayTableViewController.swift in Sources */,
C0FEAF5F27E14C52000A7648 /* ForayDetailViewController.swift in Sources */,
C04EDE4427E4298D00D83005 /* ForayNewTableViewCell.swift in Sources */,
C04B45A427DEF117001451A3 /* AppDelegate.swift in Sources */,
+ C011E4F327E6216C00C248D6 /* ForayItems.swift in Sources */,
C04B45A627DEF117001451A3 /* SceneDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
diff --git a/foray/ForayItems.swift b/foray/ForayItems.swift
new file mode 100644
index 0000000..f1a1089
--- /dev/null
+++ b/foray/ForayItems.swift
@@ -0,0 +1,25 @@
+//
+// ForayItems.swift
+// foray
+//
+// Created by Nicholas Tay on 20/3/2022.
+//
+
+import Foundation
+
+enum ItemType: String, Decodable {
+ case item
+ case quest
+}
+
+struct YearSection {
+ var year: Date
+ var items: [PenguinItem]
+}
+
+struct PenguinItem: Decodable {
+ var type: ItemType
+ var releaseDate: Date
+ var id: String
+ var name: String
+}
diff --git a/foray/ForayNetworkManager.swift b/foray/ForayNetworkManager.swift
new file mode 100644
index 0000000..ab1e2b5
--- /dev/null
+++ b/foray/ForayNetworkManager.swift
@@ -0,0 +1,50 @@
+//
+// ForayNetworkManager.swift
+// foray
+//
+// Created by Nicholas Tay on 20/3/2022.
+//
+
+import Foundation
+
+class ForayNetworkManager {
+ static let shared = ForayNetworkManager()
+
+ var basicUsername: String? = nil
+ var basicPassword: String? = nil
+
+ // Reuse JSON decoder, allows for customisation of things like date decode if required
+ var jsonDecoder: JSONDecoder = {
+ let jd = JSONDecoder()
+ // Defaults to year-month-date format
+ jd.dateDecodingStrategy = .custom({ (decoder) -> Date in
+ let container = try decoder.singleValueContainer()
+ let dateStr = try container.decode(String.self)
+
+ let dateFormat = DateFormatter()
+ dateFormat.dateFormat = "yyyy-MM-dd"
+
+ return dateFormat.date(from: dateStr)!
+ })
+ return jd
+ }()
+
+ func get<T: Decodable>(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!)
+
+ // Possibly passing back to UI, need to do it on the main thread (I think due to async?)
+ DispatchQueue.main.async { onComplete(items) }
+ }).resume()
+ }
+}
diff --git a/foray/ForayTableViewController.swift b/foray/ForayTableViewController.swift
index a7581d2..2732fce 100644
--- a/foray/ForayTableViewController.swift
+++ b/foray/ForayTableViewController.swift
@@ -7,29 +7,6 @@
import UIKit
-enum ItemType: String, Decodable {
- case item
- case quest
-}
-
-struct PenguinItem: Decodable {
- var type: ItemType
- var releaseDate: Date
- var id: String
- var name: String
-}
-
-struct YearSection {
- var year: Date
- var items: [PenguinItem]
-}
-
-private func parseDate(_ str : String) -> Date {
- let dateFormat = DateFormatter()
- dateFormat.dateFormat = "yyyy-MM-dd"
- return dateFormat.date(from: str)!
-}
-
private func firstDayOfYear(date: Date) -> Date {
let calendar = Calendar.current
let components = calendar.dateComponents([.year], from: date)
@@ -75,50 +52,24 @@ class ForayTableViewController: UITableViewController {
}
func reloadApiData() {
- loadApiData(onComplete: { (apiItems) in
- var items = apiItems
- items.sort { (lhs, rhs) in lhs.releaseDate < rhs.releaseDate }
-
- let groups = Dictionary(grouping: apiItems) { (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()
- self.refreshControl?.endRefreshing()
- })
- }
-
- func loadApiData(onComplete: @escaping ([PenguinItem]) -> ()) {
- var request = URLRequest(url: URL(string: "https://users.windblume.net/~nick/upload/dummy.json")!)
- request.cachePolicy = .reloadRevalidatingCacheData // Needed otherwise default caching policy seems not to check properly
-
- // Basic auth if required
- //let authData = ("ext:PASSWORD").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)
+ ForayNetworkManager.shared.get(
+ url: "https://users.windblume.net/~nick/upload/dummy.json",
+ onComplete: { (apiItems: [PenguinItem]) in
+ var items = apiItems
+ items.sort { (lhs, rhs) in lhs.releaseDate < rhs.releaseDate }
+
+ let groups = Dictionary(grouping: apiItems) { (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()
+ self.refreshControl?.endRefreshing()
})
- let items = try! jsonDecoder.decode([PenguinItem].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