// // NetworkManager.swift // iOSFirst // // Created by 孙宇峰 on 2023/2/22. // import Foundation import Moya import Alamofire import HandyJSON import RxSwift import SwiftyJSON /// 超时时长 private var requestTimeOut:Double = 30 ///endpointClosure public let myEndpointClosure = { (target: TargetType) -> Endpoint in ///这里的endpointClosure和网上其他实现有些不太一样。 ///主要是为了解决URL带有?无法请求正确的链接地址的bug let url = target.baseURL.absoluteString + target.path var endpoint = Endpoint( url: url, sampleResponseClosure: { .networkResponse(200, target.sampleData) }, method: target.method, task: target.task, httpHeaderFields: target.headers ) switch target { default: requestTimeOut = 30//设置默认的超时时长 return endpoint } } public let requestClosure = { (endpoint: Endpoint, done: MoyaProvider.RequestResultClosure) in do { var request = try endpoint.urlRequest() //设置请求时长 request.timeoutInterval = requestTimeOut // 打印请求参数 if let requestData = request.httpBody { log.info("\(request.url!)"+"\n"+"\(request.httpMethod ?? "")"+"发送参数"+"\(String(data: request.httpBody!, encoding: String.Encoding.utf8) ?? "")") }else{ log.info("\(request.url!)"+"\(String(describing: request.httpMethod))") } if let header = request.allHTTPHeaderFields { log.info("请求头内容\(header)") } done(.success(request)) } catch { done(.failure(MoyaError.underlying(error, nil))) } } /// NetworkActivityPlugin插件用来监听网络请求 public let networkPlugin = NetworkActivityPlugin.init { (changeType, targetType) in log.info("networkPlugin \(changeType)") //targetType 是当前请求的基本信息 switch(changeType){ case .began: log.info("开始请求网络") case .ended: log.info("结束") } } // https://github.com/Moya/Moya/blob/master/docs/Providers.md 参数使用说明 //stubClosure 用来延时发送网络请求 final class TdwMoyaPlugin: PluginType { public func prepare(_ request: URLRequest, target: TargetType) -> URLRequest { var request = request request.addValue("token值", forHTTPHeaderField: "token名字") return request } } let accountProvider = MoyaProvider(endpointClosure: myEndpointClosure, requestClosure: requestClosure, plugins: [networkPlugin], trackInflights: false) public class NetworkManaer{ /// 使用Moya的请求封装 /// /// - Parameters: /// - target: 请求API,TargetType里的枚举值 /// - success: 成功的回调 /// - error: 连接服务器成功但是数据获取失败 /// - failure: 连接服务器失败 public class func request(_ target: T, success: @escaping((U) -> Void), failure: ((Int?, String) ->Void)?) { let provider = MoyaProvider( endpointClosure: myEndpointClosure, requestClosure: requestClosure, plugins: [networkPlugin], trackInflights: false // networkLoggerPlugin ) provider.request(target) { result in switch result { case let .success(response): // let json = try? response.mapString() // let responseObject = try? response.mapJSON() // JhLog( responseObject ?? "" ); do { // *********** 这里可以统一处理错误码,弹出提示信息 *********** let resObject = try? response.mapJSON() let responseObject = JSON(resObject ?? "") let code = responseObject["code"].intValue let msg = String(describing: responseObject["msg"]) switch (code) { case 0 : let dictionary=responseObject["obj"].dictionaryObject let responseData=U.deserialize(from: dictionary) log.info(responseData?.toJSONString()) // 数据返回正确 success(responseData!) case 2: // 请重新登录 failure!(code,msg) alertLogin(msg) default: // 其他错误 failureHandle(failure: failure, stateCode: code, message: msg) } } case let .failure(error): let statusCode = error.response?.statusCode ?? 1000 let message = "请求出错,错误码:" + String(statusCode) log.error(message) failureHandle(failure: failure, stateCode: statusCode, message: error.errorDescription ?? message) } } // 错误处理 - 弹出错误信息 func failureHandle(failure: ((Int?, String) ->Void)? , stateCode: Int?, message: String) { // Alert.show(type: .error, text: message) //弹出错误信息 failure?(stateCode ,message) } // 登录弹窗 - 弹出是否需要登录的窗口 func alertLogin(_ title: String?) { // TODO: 跳转到登录页的操作: } } // MARK: - 打印日志 // static let networkLoggerPlugin = NetworkLoggerPlugin(verbose: true, cURL: true, requestDataFormatter: { data -> String in // return String(data: data, encoding: .utf8) ?? "" // }) { data -> (Data) in // do { // let dataAsJSON = try JSONSerialization.jsonObject(with: data) // let prettyData = try JSONSerialization.data(withJSONObject: dataAsJSON, options: .prettyPrinted) // return prettyData // } catch { // return data // } // } }