Observable+Response.swift 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import Foundation
  2. import RxSwift
  3. #if !COCOAPODS
  4. import Moya
  5. #endif
  6. #if canImport(UIKit)
  7. import UIKit.UIImage
  8. #elseif canImport(AppKit)
  9. import AppKit.NSImage
  10. #endif
  11. /// Extension for processing raw NSData generated by network access.
  12. public extension ObservableType where Element == Response {
  13. /// Filters out responses that don't fall within the given range, generating errors when others are encountered.
  14. func filter<R: RangeExpression>(statusCodes: R) -> Observable<Element> where R.Bound == Int {
  15. return flatMap { Observable.just(try $0.filter(statusCodes: statusCodes)) }
  16. }
  17. /// Filters out responses that has the specified `statusCode`.
  18. func filter(statusCode: Int) -> Observable<Element> {
  19. return flatMap { Observable.just(try $0.filter(statusCode: statusCode)) }
  20. }
  21. /// Filters out responses where `statusCode` falls within the range 200 - 299.
  22. func filterSuccessfulStatusCodes() -> Observable<Element> {
  23. return flatMap { Observable.just(try $0.filterSuccessfulStatusCodes()) }
  24. }
  25. /// Filters out responses where `statusCode` falls within the range 200 - 399
  26. func filterSuccessfulStatusAndRedirectCodes() -> Observable<Element> {
  27. return flatMap { Observable.just(try $0.filterSuccessfulStatusAndRedirectCodes()) }
  28. }
  29. /// Maps data received from the signal into an Image. If the conversion fails, the signal errors.
  30. func mapImage() -> Observable<Image> {
  31. return flatMap { Observable.just(try $0.mapImage()) }
  32. }
  33. /// Maps data received from the signal into a JSON object. If the conversion fails, the signal errors.
  34. func mapJSON(failsOnEmptyData: Bool = true) -> Observable<Any> {
  35. return flatMap { Observable.just(try $0.mapJSON(failsOnEmptyData: failsOnEmptyData)) }
  36. }
  37. /// Maps received data at key path into a String. If the conversion fails, the signal errors.
  38. func mapString(atKeyPath keyPath: String? = nil) -> Observable<String> {
  39. return flatMap { Observable.just(try $0.mapString(atKeyPath: keyPath)) }
  40. }
  41. /// Maps received data at key path into a Decodable object. If the conversion fails, the signal errors.
  42. func map<D: Decodable>(_ type: D.Type, atKeyPath keyPath: String? = nil, using decoder: JSONDecoder = JSONDecoder(), failsOnEmptyData: Bool = true) -> Observable<D> {
  43. return flatMap { Observable.just(try $0.map(type, atKeyPath: keyPath, using: decoder, failsOnEmptyData: failsOnEmptyData)) }
  44. }
  45. }
  46. public extension ObservableType where Element == ProgressResponse {
  47. /**
  48. Filter completed progress response and maps to actual response
  49. - returns: response associated with ProgressResponse object
  50. */
  51. func filterCompleted() -> Observable<Response> {
  52. return self
  53. .filter { $0.completed }
  54. .flatMap { progress -> Observable<Response> in
  55. // Just a formatlity to satisfy the compiler (completed progresses have responses).
  56. switch progress.response {
  57. case .some(let response): return .just(response)
  58. case .none: return .empty()
  59. }
  60. }
  61. }
  62. /**
  63. Filter progress events of current ProgressResponse
  64. - returns: observable of progress events
  65. */
  66. func filterProgress() -> Observable<Double> {
  67. return self.filter { !$0.completed }.map { $0.progress }
  68. }
  69. }