created singleton to just fetch data for a decodable. this doesn't handle any customization for a URLRequest, just dealing with a public url for now.

Signed-off-by: Matt Bruce <mbrucedogs@gmail.com>
This commit is contained in:
Matt Bruce 2025-01-20 17:05:20 -06:00
parent 7f2e03ed6b
commit 255356ff19

View File

@ -23,3 +23,50 @@ public enum NetworkServiceError: Error {
/// An unexpected, uncategorized error occurred. /// An unexpected, uncategorized error occurred.
case unknownError(Error) case unknownError(Error)
} }
public class NetworkService {
public static let shared = NetworkService() // Default shared instance
private let session: URLSession
/// Public initializer to allow customization
public init(session: URLSession = .shared) {
self.session = session
}
/// Fetches data from a URL and decodes it into a generic Decodable type.
/// - Parameters:
/// - endpoint: The url to fetch data from.
/// - type: The type to decode the data into.
/// - Throws: A `ServiceError` for network, decoding, or unexpected errors.
/// - Returns: The decoded object of the specified type.
public func fetchData<T: Decodable>(from endpoint: String, as type: T.Type) async throws -> T {
do {
//ensure a valid URL
guard let url = URL(string: endpoint) else {
throw NetworkServiceError.invalidURL
}
// Perform network request
let (data, response) = try await URLSession.shared.data(for: URLRequest(url: url))
// Validate HTTP response
guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else {
throw NetworkServiceError.invalidResponse
}
// Decode the response into the specified type
return try JSONDecoder().decode(T.self, from: data)
} catch let urlError as URLError {
throw NetworkServiceError.networkError(urlError)
} catch let decodingError as DecodingError {
throw NetworkServiceError.decodingError(decodingError)
} catch {
throw NetworkServiceError.unknownError(error)
}
}
}