mirror of
https://github.com/ivanvorobei/SwiftUI.git
synced 2026-04-26 02:28:36 +02:00
Combine examples
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// Publisher.Extension.swift
|
||||
// GitHubSearchWithSwiftUI
|
||||
//
|
||||
// Created by John Holdsworth on 09/07/2019.
|
||||
// Copyright © 2019 jp.marty-suzuki. All rights reserved.
|
||||
//
|
||||
|
||||
import Combine
|
||||
|
||||
extension Publisher {
|
||||
|
||||
/// - seealso: https://twitter.com/peres/status/1136132104020881408
|
||||
func flatMapLatest<T: Publisher>(_ transform: @escaping (Self.Output) -> T) -> Publishers.SwitchToLatest<T, Publishers.Map<Self, T>> where T.Failure == Self.Failure {
|
||||
map(transform).switchToLatest()
|
||||
}
|
||||
}
|
||||
|
||||
extension Publisher {
|
||||
|
||||
static func empty() -> AnyPublisher<Output, Failure> {
|
||||
return Publishers.Empty()
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
static func just(_ output: Output) -> AnyPublisher<Output, Failure> {
|
||||
return Just(output)
|
||||
.catch { _ in AnyPublisher<Output, Failure>.empty() }
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
static func fail(_ error: Failure) -> AnyPublisher<Output, Failure> {
|
||||
return Publishers.Fail(error: error)
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user