Skip to content

Instantly share code, notes, and snippets.

@raxityo
Created July 30, 2020 19:24
Show Gist options
  • Save raxityo/6ad244787f413c64ed88120c952b47bf to your computer and use it in GitHub Desktop.
Save raxityo/6ad244787f413c64ed88120c952b47bf to your computer and use it in GitHub Desktop.
import Alamofire
import RxAlamofire
import RxSwift
import UIKit
/// Extension for Observable<DataRequest>
extension ObservableType where Element == DataRequest {
/// Fetch this request and decode the decodable as given type or inferred type.
///
/// Either `type` or inferred type must be provided for this to work.
///
/// Example Usages:
/// ```
/// // given:
/// struct Post: Codable {
/// let userId: Int
/// let id: Int
/// let title: String
/// let body: String
/// }
///
/// let session = Session(configuration: URLSessionConfiguration.af.default)
///
/// // Get Posts by explicitly providing the type
/// session.rx
/// .requestData(.get, "https://jsonplaceholder.typicode.com/posts")
/// .fetch([Post].self)
/// .subscribe()
///
/// // Get Posts by inferring its type based on the usage:
/// session.rx
/// .requestData(.get, "https://jsonplaceholder.typicode.com/posts")
/// .fetch()
/// .subscribe(onSuccess: { (posts: [Post]) in print(posts) })
/// ```
///
/// - parameter type: Optional type to decode the response as.
/// - returns: Observable of Codable type.
func fetch<D: Decodable>(_ type: D.Type? = nil) -> Single<D> {
observeOn(backgroundScheduler)
.responseData()
.asSingle()
.log()
.validateResponse()
.decode(type: type)
.observeOn(MainScheduler.instance)
}
}
extension PrimitiveSequence where Trait == SingleTrait, Element == (HTTPURLResponse, Data) {
func log() -> Single<(HTTPURLResponse, Data)> {
map { resp -> (HTTPURLResponse, Data) in
let (response, _) = resp
if response.statusCode >= 400 {
logWarn(String(describing: response))
return resp
}
return resp
}
}
func validateResponse() -> Single<Data> {
map {
let (response, data) = $0
guard response.statusCode < 400 else {
let error = APIError.from(
statusCode: response.statusCode,
value: data
)
logDebug(response.description)
logError(error.message)
throw error
}
return data
}
}
}
extension PrimitiveSequence where Trait == SingleTrait, Element == Data {
func decode<D: Decodable>(type: D.Type? = nil) -> Single<D> {
map {
try JSONDecoder().decode(type.self ?? D.self, from: $0)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment