Networking with URLSession

Downloads/uploads (session.download(from:), session.upload(for:from:)), progress via AsyncBytes (session.bytes(from:)), background sessions (iOS), WebSockets (URLSessionWebSocketTask), caching (URLCache), configuration (URLSessionConfiguration.ephemeral), and authentication challenges.

App Transport Security (iOS/macOS) requires HTTPS by default.

Libraries: Alamofire, swift-openapi-generator (generate type-safe clients from OpenAPI specs), AsyncHTTPClient (server-side).

struct APIClient {
    let baseURL: URL
    let session: URLSession = .shared

    func get<T: Decodable>(_ path: String, as type: T.Type = T.self) async throws -> T {
        var request = URLRequest(url: baseURL.appending(path: path))
        request.setValue("application/json", forHTTPHeaderField: "Accept")
        request.timeoutInterval = 15
        let (data, response) = try await session.data(for: request)
        guard let http = response as? HTTPURLResponse else { throw APIError.invalidResponse }
        guard (200..<300).contains(http.statusCode) else { throw APIError.status(http.statusCode, data) }
        return try JSONDecoder().decode(T.self, from: data)
    }

    func post<Body: Encodable, T: Decodable>(_ path: String, body: Body) async throws -> T {
        var request = URLRequest(url: baseURL.appending(path: path))
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.httpBody = try JSONEncoder().encode(body)
        let (data, _) = try await session.data(for: request)
        return try JSONDecoder().decode(T.self, from: data)
    }
}

enum APIError: Error { case invalidResponse, stat
…