説明なし

NetworkApi.swift 11KB

    // // NetworkApi.swift // PaiAi // // Created by FFIB on 2017/9/29. // Copyright © 2017年 yb. All rights reserved. // import Foundation import Alamofire class NetworkApi { open static let share = NetworkApi() typealias FailureHandler = ((HTTPURLResponse?) -> Void) typealias ProgressHandler = (() -> Void) typealias FinishHandler = (() -> Void) private let sessionManager: SessionManager private var httpRequests = [Request]() private var currentRequests: Request? = nil var finishHander: FinishHandler = {} var failureHandler: FailureHandler = { response in guard let status = response?.statusCode else { return } let manager = NetworkReachabilityManager() manager?.listener = { networkStatus in guard let visibleView = UIApplication.shared.keyWindow else{ return } if networkStatus == .notReachable || networkStatus == .unknown { FFToastView.showToast(inView: visibleView, withText: "当前网络状态不好") return } if status >= 500 { FFToastView.showToast(inView: visibleView, withText: "服务器出现异常") }else if status >= 400 { assert(true, "client error") }else if status >= 300 { assert(true, "重定向问题") } } } init() { let configuration = URLSessionConfiguration.default configuration.httpAdditionalHeaders = SessionManager.defaultHTTPHeaders sessionManager = Alamofire.SessionManager(configuration: configuration) sessionManager.retrier = OAuthHandler() } @discardableResult public func failure(handler: @escaping FailureHandler) -> NetworkApi { failureHandler = handler return self } @discardableResult public func finish(handler: @escaping FinishHandler) -> NetworkApi { finishHander = handler return self } @discardableResult public func post<T: NetworkRequest>(request: T, handler: @escaping ([T.NetworkResponse]) -> Void) -> NetworkApi where T.NetworkResponse: GroupParsable { let request = sessionManager.request(request.host + request.path.rawValue, method: .post, parameters: request.parameter) .responseJSON {[weak self] (res) in guard let weakself = self else { return } weakself.finishHander() if let index = weakself.httpRequests.index(where: { $0.request == res.request }) { weakself.httpRequests.remove(at: index) } switch res.result { case .success(let value): guard let data = value as? [String: AnyObject] else { return } handler(T.NetworkResponse.parse(datas: data)) case .failure(_): weakself.failureHandler(res.response) } } httpRequests.append(request) return self } @discardableResult public func post<T: NetworkRequest>(request: T, handler: @escaping (T.NetworkResponse) -> Void) -> NetworkApi where T.NetworkResponse: SingleParsable{ let request = sessionManager.request(request.host + request.path.rawValue, method: .post, parameters: request.parameter) .responseJSON {[weak self] (res) in guard let weakself = self else { return } weakself.finishHander() if let index = weakself.httpRequests.index(where: { $0.request == res.request }) { weakself.httpRequests.remove(at: index) } switch res.result { case .success(let value): guard let data = value as? [String: AnyObject] else { return } handler(T.NetworkResponse.parse(data: data)) case .failure(_): weakself.failureHandler(res.response) } } httpRequests.append(request) return self } @discardableResult public func post(param: [String: AnyObject], url: Interfaces, handler: @escaping ([String: AnyObject]) -> Void) -> NetworkApi { let request = sessionManager.request(Interfaces.baseUrl.rawValue + url.rawValue, method: .post, parameters: param) .responseJSON {[weak self] (res) in guard let weakself = self else { return } weakself.finishHander() switch res.result { case .success(let value): guard let data = value as? [String: AnyObject] else { return } handler(data) case .failure(_): weakself.failureHandler(res.response) } if let index = weakself.httpRequests.index(where: { $0.request == res.request }) { weakself.httpRequests.remove(at: index) } } httpRequests.append(request) return self } @discardableResult public func get(param: [String: AnyObject]?, url: String, handler: @escaping ([String: AnyObject]) -> Void) -> NetworkApi { let final = url.hasPrefix("http") ? url : Interfaces.baseUrl.rawValue + url let request = sessionManager.request(final, method: .get, parameters: param) .responseJSON {[weak self] (res) in guard let weakself = self else { return } weakself.finishHander() if let index = weakself.httpRequests.index(where: { $0.request == res.request }) { weakself.httpRequests.remove(at: index) } switch res.result { case .success(let value): guard let data = value as? [String: AnyObject] else { return } handler(data) case .failure(_): weakself.failureHandler(res.response) } } httpRequests.append(request) return self } @discardableResult public func get<T: NetworkRequest>(request: T, handler: @escaping ([T.NetworkResponse]) -> Void) -> NetworkApi where T.NetworkResponse: GroupParsable { let request = sessionManager.request(request.host + request.path.rawValue, method: .get, parameters: request.parameter) .responseJSON {[weak self] (res) in guard let weakself = self else { return } weakself.finishHander() if let index = weakself.httpRequests.index(where: { $0.request == res.request }) { weakself.httpRequests.remove(at: index) } switch res.result { case .success(let value): guard let data = value as? [String: AnyObject] else { return } handler(T.NetworkResponse.parse(datas: data)) case .failure(_): weakself.failureHandler(res.response) } } httpRequests.append(request) return self } @discardableResult public func download<T: NetworkRequest>(request: T) -> NetworkApi { sessionManager.download(request.host + request.path.rawValue, method: .get, parameters: request.parameter, to: nil) return self } @discardableResult public func upload(param: [String: AnyObject], url: String, handler: @escaping ([String: AnyObject]) -> Void) -> NetworkApi { sessionManager.upload(multipartFormData: { (multiPartData) in for (key, value) in param { if let v = value as? FileModel { multiPartData.append(v.fileData, withName: v.name, fileName: v.fileName, mimeType: v.mimeType) }else { var res: Data if let v = value as? String, let data = v.data(using: String.Encoding.utf8) { res = data }else if let v = value as? NSNumber, let data = "\(v)".data(using: String.Encoding.utf8){ res = data }else { continue } multiPartData.append(res, withName: key) } } }, to: Interfaces.baseUrl.rawValue + url) {[weak self] (res) in guard let weakself = self else { return } weakself.finishHander() switch res { case .failure( _): break case .success(let request,_,_): request.responseJSON(completionHandler: { (response) in guard let value = response.value as? [String: AnyObject] else { return } handler(value) }) } } return self } deinit { httpRequests.forEach { (request) in request.cancel() } } } //extension request retrier extension NetworkApi { public struct OAuthHandler: RequestRetrier { init() {} public func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion) { if let response = request.response, response.statusCode == 401 { completion(true, 1.0) // 1秒后重试 } else { completion(false, 0.0) // 不重连 } } } }