Issue #864

Since async URLSession.shared.data is available in iOS 15+, we can build a custom one with withCheckedThrowingContinuation

import UIKit

enum HTTPMethod: String {
    case get = "GET"
    case post = "POST"
}

extension URLSession {
    func asyncData(
        with url: URL,
        method: HTTPMethod = .get,
        headers: [String: String] = [:],
        body: Data? = nil
    ) async throws -> Data {
        var request = URLRequest(url: url)
        request.httpMethod = method.rawValue
        request.allHTTPHeaderFields = [
            "Content-Type": "application/json"
        ]
        request.httpBody = body
        headers.forEach { key, value in
            request.allHTTPHeaderFields?[key] = value
        }
        return try await asyncData(with: request)
    }

    func asyncData(with request: URLRequest) async throws -> Data {
        try await withCheckedThrowingContinuation { (con: CheckedContinuation<Data, Error>) in
            let task = URLSession.shared.dataTask(with: request) { data, _, error in
                if let error = error {
                    con.resume(throwing: error)
                } else if let data = data {
                    con.resume(returning: data)
                } else {
                    con.resume(returning: Data())
                }
            }

            task.resume()
        }
    }
}