iOS-study
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

NetworkManager.swift 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. //
  2. // NetworkManager.swift
  3. // iOSFirst
  4. //
  5. // Created by 孙宇峰 on 2023/2/22.
  6. //
  7. import Foundation
  8. import Moya
  9. import Alamofire
  10. import HandyJSON
  11. import RxSwift
  12. import SwiftyJSON
  13. /// 超时时长
  14. private var requestTimeOut:Double = 30
  15. ///endpointClosure
  16. public let myEndpointClosure = { (target: TargetType) -> Endpoint in
  17. ///这里的endpointClosure和网上其他实现有些不太一样。
  18. ///主要是为了解决URL带有?无法请求正确的链接地址的bug
  19. let url = target.baseURL.absoluteString + target.path
  20. var endpoint = Endpoint(
  21. url: url,
  22. sampleResponseClosure: { .networkResponse(200, target.sampleData) },
  23. method: target.method,
  24. task: target.task,
  25. httpHeaderFields: target.headers
  26. )
  27. switch target {
  28. default:
  29. requestTimeOut = 30//设置默认的超时时长
  30. return endpoint
  31. }
  32. }
  33. public let requestClosure = { (endpoint: Endpoint, done: MoyaProvider.RequestResultClosure) in
  34. do {
  35. var request = try endpoint.urlRequest()
  36. //设置请求时长
  37. request.timeoutInterval = requestTimeOut
  38. // 打印请求参数
  39. if let requestData = request.httpBody {
  40. log.info("\(request.url!)"+"\n"+"\(request.httpMethod ?? "")"+"发送参数"+"\(String(data: request.httpBody!, encoding: String.Encoding.utf8) ?? "")")
  41. }else{
  42. log.info("\(request.url!)"+"\(String(describing: request.httpMethod))")
  43. }
  44. if let header = request.allHTTPHeaderFields {
  45. log.info("请求头内容\(header)")
  46. }
  47. done(.success(request))
  48. } catch {
  49. done(.failure(MoyaError.underlying(error, nil)))
  50. }
  51. }
  52. /// NetworkActivityPlugin插件用来监听网络请求
  53. public let networkPlugin = NetworkActivityPlugin.init { (changeType, targetType) in
  54. log.info("networkPlugin \(changeType)")
  55. //targetType 是当前请求的基本信息
  56. switch(changeType){
  57. case .began:
  58. log.info("开始请求网络")
  59. case .ended:
  60. log.info("结束")
  61. }
  62. }
  63. // https://github.com/Moya/Moya/blob/master/docs/Providers.md 参数使用说明
  64. //stubClosure 用来延时发送网络请求
  65. final class TdwMoyaPlugin: PluginType {
  66. public func prepare(_ request: URLRequest, target: TargetType) -> URLRequest {
  67. var request = request
  68. request.addValue("token值", forHTTPHeaderField: "token名字")
  69. return request
  70. }
  71. }
  72. let accountProvider = MoyaProvider<AccountService>(endpointClosure: myEndpointClosure, requestClosure: requestClosure, plugins: [networkPlugin], trackInflights: false)
  73. public class NetworkManaer{
  74. /// 使用Moya的请求封装
  75. ///
  76. /// - Parameters:
  77. /// - target: 请求API,TargetType里的枚举值
  78. /// - success: 成功的回调
  79. /// - error: 连接服务器成功但是数据获取失败
  80. /// - failure: 连接服务器失败
  81. public class func request<T: TargetType,U: HandyJSON>(_ target: T, success: @escaping((U) -> Void), failure: ((Int?, String) ->Void)?) {
  82. let provider = MoyaProvider<T>(
  83. endpointClosure: myEndpointClosure,
  84. requestClosure: requestClosure,
  85. plugins: [networkPlugin],
  86. trackInflights: false
  87. // networkLoggerPlugin
  88. )
  89. provider.request(target) { result in
  90. switch result {
  91. case let .success(response):
  92. // let json = try? response.mapString()
  93. // let responseObject = try? response.mapJSON()
  94. // JhLog( responseObject ?? "" );
  95. do {
  96. // *********** 这里可以统一处理错误码,弹出提示信息 ***********
  97. let resObject = try? response.mapJSON()
  98. let responseObject = JSON(resObject ?? "")
  99. let code = responseObject["code"].intValue
  100. let msg = String(describing: responseObject["msg"])
  101. switch (code) {
  102. case 0 :
  103. let dictionary=responseObject["obj"].dictionaryObject
  104. let responseData=U.deserialize(from: dictionary)
  105. log.info(responseData?.toJSONString())
  106. // 数据返回正确
  107. success(responseData!)
  108. case 2:
  109. // 请重新登录
  110. failure!(code,msg)
  111. alertLogin(msg)
  112. default:
  113. // 其他错误
  114. failureHandle(failure: failure, stateCode: code, message: msg)
  115. }
  116. }
  117. case let .failure(error):
  118. let statusCode = error.response?.statusCode ?? 1000
  119. let message = "请求出错,错误码:" + String(statusCode)
  120. log.error(message)
  121. failureHandle(failure: failure, stateCode: statusCode, message: error.errorDescription ?? message)
  122. }
  123. }
  124. // 错误处理 - 弹出错误信息
  125. func failureHandle(failure: ((Int?, String) ->Void)? , stateCode: Int?, message: String) {
  126. // Alert.show(type: .error, text: message)
  127. //弹出错误信息
  128. failure?(stateCode ,message)
  129. }
  130. // 登录弹窗 - 弹出是否需要登录的窗口
  131. func alertLogin(_ title: String?) {
  132. // TODO: 跳转到登录页的操作:
  133. }
  134. }
  135. // MARK: - 打印日志
  136. // static let networkLoggerPlugin = NetworkLoggerPlugin(verbose: true, cURL: true, requestDataFormatter: { data -> String in
  137. // return String(data: data, encoding: .utf8) ?? ""
  138. // }) { data -> (Data) in
  139. // do {
  140. // let dataAsJSON = try JSONSerialization.jsonObject(with: data)
  141. // let prettyData = try JSONSerialization.data(withJSONObject: dataAsJSON, options: .prettyPrinted)
  142. // return prettyData
  143. // } catch {
  144. // return data
  145. // }
  146. // }
  147. }