//===----------------------------------------------------------------------===// // // This source file is part of the AmiiboService open source project // // Copyright (c) 2023 Röck+Cöde VoF. and the AmiiboService project authors // Licensed under the EUPL 1.2 or later. // // See LICENSE.txt for license information // See CONTRIBUTORS.txt for the list of AmiiboService project authors // //===----------------------------------------------------------------------===// #if os(iOS) || os(macOS) || os(tvOS) || os(watchOS) import Communications import Foundation struct AmiiboClient { // MARK: Properties private let session: URLSession private let decoder = JSONDecoder() private let makeURLRequest = MakeURLRequestUseCase() // MARK: Initialisers init(configuration: URLSessionConfiguration) { session = .init(configuration: configuration) } // MARK: Functions func setDateDecodingStrategy(_ dateDecodingStrategy: JSONDecoder.DateDecodingStrategy) { decoder.dateDecodingStrategy = dateDecodingStrategy } } // MARK: - Client extension AmiiboClient: Client { // MARK: Functions func request( endpoint: some Endpoint, as model: Model.Type ) async throws -> Model where Model : Decodable { let urlRequest = try makeURLRequest(endpoint: endpoint) let (data, response) = try await session.data(for: urlRequest) try check(response) return try decoder.decode(model, from: data) } } // MARK: - Helpers private extension AmiiboClient { // MARK: Functions func check(_ response: URLResponse) throws { guard let urlResponse = response as? HTTPURLResponse, let responseCode = HTTPResponseCode(rawValue: urlResponse.statusCode) else { throw AmiiboClientError.responseCodeNotFound } guard responseCode == .ok else { throw AmiiboClientError.responseCode(responseCode.rawValue) } } } #endif