diff --git a/SwiftLeeds/Network/URLSession.swift b/SwiftLeeds/Network/URLSession.swift index 3244324..bee9b5a 100644 --- a/SwiftLeeds/Network/URLSession.swift +++ b/SwiftLeeds/Network/URLSession.swift @@ -1,10 +1,3 @@ -// -// URLSession.swift -// SwiftLeeds -// -// Created by Matthew Gallagher on 24/09/2023. -// - import Foundation public extension URLSession { @@ -13,49 +6,41 @@ public extension URLSession { configuration.waitsForConnectivity = true configuration.timeoutIntervalForRequest = 30 configuration.timeoutIntervalForResource = 30 - configuration.urlCache = nil - configuration.requestCachePolicy = .reloadIgnoringLocalAndRemoteCacheData + configuration.requestCachePolicy = .useProtocolCachePolicy return URLSession(configuration: configuration) }() - func cached(_ request: Request, using decoder: JSONDecoder = .init(), - dateDecodingStrategy: JSONDecoder.DateDecodingStrategy = .deferredToDate, - fileManager: FileManager = .default, filename: String? = nil) async throws -> Response { - let filename = filename ?? request.url.lastPathComponent - let path = fileManager.temporaryDirectory.appendingPathComponent(filename) - - guard let data = fileManager.contents(atPath: path.path.appending(".json")) else { throw NetworkError.cacheNotFound } - - let decoded = Task.detached(priority: .userInitiated) { - try Task.checkCancellation() - decoder.dateDecodingStrategy = dateDecodingStrategy - return try decoder.decode(Response.self, from: data) - } - - return try await decoded.value - } - - func decode(_ request: Request, using decoder: JSONDecoder = .init(), - dateDecodingStrategy: JSONDecoder.DateDecodingStrategy?, - fileManager: FileManager = .default, filename: String? = nil) async throws -> Response { - let filename = filename ?? request.url.lastPathComponent - let path = fileManager.temporaryDirectory.appendingPathComponent("\(filename).json") - + func decode( + _ request: Request, + using decoder: JSONDecoder = .init(), + dateDecodingStrategy: JSONDecoder.DateDecodingStrategy?, + fileManager: FileManager = .default, + filename: String? = nil + ) async throws -> Response { let decoded = Task.detached(priority: .userInitiated) { do { let (data, response) = try await self.data(for: request.urlRequest) try Task.checkCancellation() - guard let response = response as? HTTPURLResponse else { throw URLError(.badServerResponse) } + guard let response = response as? HTTPURLResponse else { + throw URLError(.badServerResponse) + } switch response.statusCode { case 200...299: break case 304: throw NetworkError.notModified default: throw NetworkError.unexpectedStatusCode(response.statusCode) } - - try data.write(to: path, options: .atomicWrite) + + let cachedResponse = CachedURLResponse( + response: response, + data: data + ) + URLCache.shared.storeCachedResponse( + cachedResponse, + for: request.urlRequest + ) if let eTagKey = request.eTagKey, let eTagValue = response.value(forHTTPHeaderField: "Etag") { UserDefaults.standard.set(eTagValue, forKey: eTagKey) diff --git a/SwiftLeeds/Views/Local/LocalViewModel.swift b/SwiftLeeds/Views/Local/LocalViewModel.swift index b7b1a58..f862646 100644 --- a/SwiftLeeds/Views/Local/LocalViewModel.swift +++ b/SwiftLeeds/Views/Local/LocalViewModel.swift @@ -29,11 +29,7 @@ class LocalViewModel: ObservableObject { let localResults = try await URLSession.awaitConnectivity.decode(Requests.local, dateDecodingStrategy: Requests.defaultDateDecodingStratergy) await updateLocal(localResults) } catch { - if let cachedResponse = try? await URLSession.shared.cached(Requests.local, dateDecodingStrategy: Requests.defaultDateDecodingStratergy) { - await updateLocal(cachedResponse) - } else { - self.error = error - } + self.error = error } } diff --git a/SwiftLeeds/Views/My Conference/MyConferenceViewModel.swift b/SwiftLeeds/Views/My Conference/MyConferenceViewModel.swift index 9bca1a2..93c50b9 100644 --- a/SwiftLeeds/Views/My Conference/MyConferenceViewModel.swift +++ b/SwiftLeeds/Views/My Conference/MyConferenceViewModel.swift @@ -19,7 +19,10 @@ class MyConferenceViewModel: ObservableObject { func loadSchedule() async throws { do { - let schedule = try await URLSession.awaitConnectivity.decode(Requests.schedule, dateDecodingStrategy: Requests.defaultDateDecodingStratergy) + let schedule = try await URLSession.awaitConnectivity.decode( + Requests.schedule, + dateDecodingStrategy: Requests.defaultDateDecodingStratergy + ) await updateSchedule(schedule) do { @@ -29,11 +32,7 @@ class MyConferenceViewModel: ObservableObject { throw(error) } } catch { - if let cachedResponse = try? await URLSession.shared.cached(Requests.schedule, dateDecodingStrategy: Requests.defaultDateDecodingStratergy) { - await updateSchedule(cachedResponse) - } else { - throw(error) - } + throw error } } diff --git a/SwiftLeeds/Views/Sponsors/SponsorsViewModel.swift b/SwiftLeeds/Views/Sponsors/SponsorsViewModel.swift index ede5fea..c2ecff1 100644 --- a/SwiftLeeds/Views/Sponsors/SponsorsViewModel.swift +++ b/SwiftLeeds/Views/Sponsors/SponsorsViewModel.swift @@ -23,11 +23,7 @@ final class SponsorsViewModel: ObservableObject { let sponsors = try await URLSession.awaitConnectivity.decode(Requests.sponsors, dateDecodingStrategy: Requests.defaultDateDecodingStratergy) await updateSponsors(sponsors) } catch { - if let cachedResponse = try? await URLSession.shared.cached(Requests.sponsors, dateDecodingStrategy: Requests.defaultDateDecodingStratergy) { - await updateSponsors(cachedResponse) - } else { - throw(error) - } + throw error } }