Observable+Extension.swift 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. //
  2. // Observable+Extension.swift
  3. // Bark
  4. //
  5. // Created by huangfeng on 2018/6/25.
  6. // Copyright © 2018 Fin. All rights reserved.
  7. //
  8. import UIKit
  9. import Moya
  10. import ObjectMapper
  11. import RxSwift
  12. import SwiftyJSON
  13. import UIKit
  14. extension Observable where Element: Moya.Response {
  15. /// 过滤 HTTP 错误,例如超时,请求失败等
  16. func filterHttpError() -> Observable<Result<Element, ApiError>> {
  17. return catchAndReturn(Element(statusCode: 599, data: Data()))
  18. .map { response -> Result<Element, ApiError> in
  19. if (200...209) ~= response.statusCode {
  20. return .success(response)
  21. } else {
  22. return .failure(ApiError.Error(info: "网络错误"))
  23. }
  24. }
  25. }
  26. /// 过滤逻辑错误,例如协议里返回 错误CODE
  27. func filterResponseError() -> Observable<Result<JSON, ApiError>> {
  28. return filterHttpError()
  29. .map { response -> Result<JSON, ApiError> in
  30. switch response {
  31. case .success(let element):
  32. do {
  33. let json = try JSON(data: element.data)
  34. if let codeStr = json["code"].rawString(),
  35. let code = Int(codeStr),
  36. code == 200
  37. {
  38. return .success(json)
  39. } else {
  40. var msg: String = ""
  41. if json["message"].exists() {
  42. msg = json["message"].rawString()!
  43. }
  44. return .failure(ApiError.Error(info: msg))
  45. }
  46. } catch {
  47. return .failure(ApiError.Error(info: error.rawString()))
  48. }
  49. case .failure(let error):
  50. return .failure(ApiError.Error(info: error.rawString()))
  51. }
  52. }
  53. }
  54. /// 将Response 转换成 JSON Model
  55. ///
  56. /// - Parameters:
  57. /// - typeName: 要转换的Model Class
  58. /// - dataPath: 从哪个节点开始转换,例如 ["data","links"]
  59. func mapResponseToObj<T: Mappable>(_ typeName: T.Type, dataPath: [String] = ["data"]) -> Observable<Result<T, ApiError>> {
  60. return filterResponseError().map { json in
  61. switch json {
  62. case .success(let json):
  63. var rootJson = json
  64. if dataPath.count > 0 {
  65. rootJson = rootJson[dataPath]
  66. }
  67. if let model: T = self.resultFromJSON(json: rootJson) {
  68. return .success(model)
  69. } else {
  70. return .failure(ApiError.Error(info: "json 转换失败"))
  71. }
  72. case .failure(let error):
  73. return .failure(error)
  74. }
  75. }
  76. }
  77. /// 将Response 转换成 JSON Model Array
  78. func mapResponseToObjArray<T: Mappable>(_ type: T.Type, dataPath: [String] = ["data"]) -> Observable<Result<[T], ApiError>> {
  79. return filterResponseError().map { json in
  80. switch json {
  81. case .success(let json):
  82. var rootJson = json
  83. if dataPath.count > 0 {
  84. rootJson = rootJson[dataPath]
  85. }
  86. var result = [T]()
  87. guard let jsonArray = rootJson.array else {
  88. return .failure(ApiError.Error(info: "Root Json 不是 Array"))
  89. }
  90. for json in jsonArray {
  91. if let jsonModel: T = self.resultFromJSON(json: json) {
  92. result.append(jsonModel)
  93. } else {
  94. return .failure(ApiError.Error(info: "json 转换失败"))
  95. }
  96. }
  97. return .success(result)
  98. case .failure(let error):
  99. return .failure(error)
  100. }
  101. }
  102. }
  103. private func resultFromJSON<T: Mappable>(jsonString: String) -> T? {
  104. return T(JSONString: jsonString)
  105. }
  106. private func resultFromJSON<T: Mappable>(json: JSON) -> T? {
  107. if let str = json.rawString() {
  108. return resultFromJSON(jsonString: str)
  109. }
  110. return nil
  111. }
  112. }