/
RxMoyaProvider.swift
71 lines (63 loc) · 2.87 KB
/
RxMoyaProvider.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import Foundation
import RxSwift
#if !COCOAPODS
import Moya
#endif
/// Subclass of MoyaProvider that returns Observable instances when requests are made. Much better than using completion closures.
open class RxMoyaProvider<Target>: MoyaProvider<Target> where Target: TargetType {
/// Initializes a reactive provider.
override public init(endpointClosure: @escaping EndpointClosure = MoyaProvider.defaultEndpointMapping,
requestClosure: @escaping RequestClosure = MoyaProvider.defaultRequestMapping,
stubClosure: @escaping StubClosure = MoyaProvider.neverStub,
manager: Manager = RxMoyaProvider<Target>.defaultAlamofireManager(),
plugins: [PluginType] = [],
trackInflights: Bool = false) {
super.init(endpointClosure: endpointClosure, requestClosure: requestClosure, stubClosure: stubClosure, manager: manager, plugins: plugins, trackInflights: trackInflights)
}
/// Designated request-making method.
open func request(_ token: Target) -> Observable<Response> {
// Creates an observable that starts a request each time it's subscribed to.
return Observable.create { observer in
let cancellableToken = self.request(token) { result in
switch result {
case let .success(response):
observer.onNext(response)
observer.onCompleted()
case let .failure(error):
observer.onError(error)
}
}
return Disposables.create {
cancellableToken.cancel()
}
}
}
}
public extension RxMoyaProvider {
public func requestWithProgress(_ token: Target) -> Observable<ProgressResponse> {
let progressBlock: (AnyObserver) -> (ProgressResponse) -> Void = { observer in
return { progress in
observer.onNext(progress)
}
}
let response: Observable<ProgressResponse> = Observable.create { observer in
let cancellableToken = self.request(token, queue: nil, progress: progressBlock(observer)) { result in
switch result {
case .success:
observer.onCompleted()
case let .failure(error):
observer.onError(error)
}
}
return Disposables.create {
cancellableToken.cancel()
}
}
// Accumulate all progress and combine them when the result comes
return response.scan(ProgressResponse()) { last, progress in
let progressObject = progress.progressObject ?? last.progressObject
let response = progress.response ?? last.response
return ProgressResponse(progress: progressObject, response: response)
}
}
}