MoyaProvider+Rx.swift 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. import Foundation
  2. import RxSwift
  3. #if !COCOAPODS
  4. import Moya
  5. #endif
  6. extension MoyaProvider: ReactiveCompatible {}
  7. public extension Reactive where Base: MoyaProviderType {
  8. /// Designated request-making method.
  9. ///
  10. /// - Parameters:
  11. /// - token: Entity, which provides specifications necessary for a `MoyaProvider`.
  12. /// - callbackQueue: Callback queue. If nil - queue from provider initializer will be used.
  13. /// - Returns: Single response object.
  14. func request(_ token: Base.Target, callbackQueue: DispatchQueue? = nil) -> Single<Response> {
  15. return Single.create { [weak base] single in
  16. let cancellableToken = base?.request(token, callbackQueue: callbackQueue, progress: nil) { result in
  17. switch result {
  18. case let .success(response):
  19. single(.success(response))
  20. case let .failure(error):
  21. single(.error(error))
  22. }
  23. }
  24. return Disposables.create {
  25. cancellableToken?.cancel()
  26. }
  27. }
  28. }
  29. /// Designated request-making method with progress.
  30. func requestWithProgress(_ token: Base.Target, callbackQueue: DispatchQueue? = nil) -> Observable<ProgressResponse> {
  31. let progressBlock: (AnyObserver) -> (ProgressResponse) -> Void = { observer in
  32. return { progress in
  33. observer.onNext(progress)
  34. }
  35. }
  36. let response: Observable<ProgressResponse> = Observable.create { [weak base] observer in
  37. let cancellableToken = base?.request(token, callbackQueue: callbackQueue, progress: progressBlock(observer)) { result in
  38. switch result {
  39. case .success:
  40. observer.onCompleted()
  41. case let .failure(error):
  42. observer.onError(error)
  43. }
  44. }
  45. return Disposables.create {
  46. cancellableToken?.cancel()
  47. }
  48. }
  49. // Accumulate all progress and combine them when the result comes
  50. return response.scan(ProgressResponse()) { last, progress in
  51. let progressObject = progress.progressObject ?? last.progressObject
  52. let response = progress.response ?? last.response
  53. return ProgressResponse(progress: progressObject, response: response)
  54. }
  55. }
  56. }