Combine examples

This commit is contained in:
John Holdsworth
2019-07-10 00:37:46 +01:00
parent f5f4d0b3d5
commit 8018d0c2a0
13 changed files with 274 additions and 91 deletions

View File

@@ -15,44 +15,26 @@ extension CombineExtension where Base == URLSession {
func send(request: URLRequest) -> AnyPublisher<Data, URLSessionError> {
AnyPublisher<Data, URLSessionError> { [base] subscriber in
let task = base.dataTask(with: request) { data, response, error in
base.dataTaskPublisher(for: request)
.mapError { URLSessionError.urlError($0) }
.flatMap { data, response -> AnyPublisher<Data, URLSessionError> in
guard let response = response as? HTTPURLResponse else {
subscriber.receive(completion: .failure(.invalidResponse))
return
return .fail(.invalidResponse)
}
guard 200..<300 ~= response.statusCode else {
let e = URLSessionError.serverError(statusCode: response.statusCode,
error: error)
subscriber.receive(completion: .failure(e))
return
return .fail(.serverErrorMessage(statusCode: response.statusCode,
data: data))
}
guard let data = data else {
subscriber.receive(completion: .failure(.noData))
return
}
if let error = error {
subscriber.receive(completion: .failure(.unknown(error)))
} else {
_ = subscriber.receive(data)
subscriber.receive(completion: .finished)
}
return .just(data)
}
// TODO: cancel task when subscriber cancelled
task.resume()
}
.eraseToAnyPublisher()
}
}
enum URLSessionError: Error {
case invalidResponse
case noData
case serverError(statusCode: Int, error: Error?)
case unknown(Error)
case serverErrorMessage(statusCode: Int, data: Data)
case urlError(URLError)
}