Created
July 30, 2020 19:24
-
-
Save raxityo/6ad244787f413c64ed88120c952b47bf to your computer and use it in GitHub Desktop.
This file contains 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 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