Forked from aronbudinszky/URLSession+async.swift
Last active
January 25, 2023 07:17
-
-
Save sherwinzadeh/67357234bcfd9c91084c1b219bf116c9 to your computer and use it in GitHub Desktop.
An extension that provides async support for URLSession data function on Linux. See: https://medium.com/hoursofoperation/use-async-urlsession-with-server-side-swift-67821a64fa91?sk=bc142f8d3b6a444253eea660646aa822
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
#if canImport(FoundationNetworking) | |
import FoundationNetworking | |
#endif | |
/// Defines the possible errors | |
public enum URLSessionAsyncErrors: Error { | |
case invalidUrlResponse, missingResponseData | |
} | |
/// An extension that provides async support for fetching a URL | |
/// | |
/// Needed because the Linux version of Swift does not support async URLSession yet. | |
public extension URLSession { | |
/// A reimplementation of `URLSession.shared.data(from: url)` required for Linux | |
/// | |
/// - Parameter url: The URL for which to load data. | |
/// - Returns: Data and response. | |
/// | |
/// - Usage: | |
/// | |
/// let (data, response) = try await URLSession.shared.asyncData(from: url) | |
func asyncData(from url: URL) async throws -> (Data, URLResponse) { | |
return try await withCheckedThrowingContinuation { continuation in | |
let task = dataTask(with: url) { data, response, error in | |
if let error = error { | |
continuation.resume(throwing: error) | |
return | |
} | |
guard let response = response as? HTTPURLResponse else { | |
continuation.resume(throwing: URLSessionAsyncErrors.invalidUrlResponse) | |
return | |
} | |
guard let data = data else { | |
continuation.resume(throwing: URLSessionAsyncErrors.missingResponseData) | |
return | |
} | |
continuation.resume(returning: (data, response)) | |
} | |
task.resume() | |
} | |
} | |
/// A reimplementation of `URLSession.shared.data(for: request)` required for Linux | |
/// | |
/// - Parameter request: The URLRequest for which to load data. | |
/// - Returns: Data and response. | |
/// | |
/// - Usage: | |
/// | |
/// let (data, response) = try await URLSession.shared.asyncData(for: request) | |
func asyncData(for request: URLRequest) async throws -> (Data, URLResponse) { | |
return try await withCheckedThrowingContinuation { continuation in | |
let task = dataTask(with: request) { data, response, error in | |
if let error = error { | |
continuation.resume(throwing: error) | |
return | |
} | |
guard let response = response as? HTTPURLResponse else { | |
continuation.resume(throwing: URLSessionAsyncErrors.invalidUrlResponse) | |
return | |
} | |
guard let data = data else { | |
continuation.resume(throwing: URLSessionAsyncErrors.missingResponseData) | |
return | |
} | |
continuation.resume(returning: (data, response)) | |
} | |
task.resume() | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have updated to support URLRequest as well as URLs. Also calling dataTask on the session itself, not the global shared one as you may have multiple.