SWNetRequest.swift 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. //
  2. // SWNetRequest.swift
  3. // LiteraryHeaven
  4. //
  5. // Created by SanW on 2017/8/2.
  6. // Copyright © 2017年 ONON. All rights reserved.
  7. //
  8. import Alamofire
  9. import UIKit
  10. // 默认超时时间
  11. public let timeoutInterval: TimeInterval = 30
  12. // MARK: - 错误
  13. /// 错误
  14. public struct PQError: Error {
  15. public var msg: String? // 提示信息
  16. public var code: Int // 错误吗
  17. public init(msg: String?, code: Int = 0) {
  18. self.msg = msg
  19. self.code = code
  20. }
  21. public var localizedDescription: String {
  22. return msg ?? ""
  23. }
  24. }
  25. // MARK: - 网络请求
  26. /// 网络请求
  27. public class SWNetRequest: NSObject {
  28. // static let share = SWNetRequest()
  29. /// 回调方法
  30. public typealias completeHander = (_ jsonObject: Any?, _ error: PQError?, _ duration: TimeInterval?) -> Void
  31. static let sessionManager: Session? = {
  32. let configuration = URLSessionConfiguration.default
  33. configuration.timeoutIntervalForRequest = timeoutInterval
  34. return Session(configuration: configuration, delegate: SessionDelegate(), serverTrustManager: nil)
  35. }()
  36. static let reTrySessionManager: Session? = {
  37. let configuration = URLSessionConfiguration.default
  38. configuration.timeoutIntervalForRequest = 5
  39. return Session(configuration: configuration, delegate: SessionDelegate(), serverTrustManager: nil)
  40. }()
  41. /// get请求
  42. public class func getRequestData(url: String, parames: [String: Any]?, encoding: ParameterEncoding = URLEncoding.default, timeoutInterval: TimeInterval = timeoutInterval, response: @escaping completeHander) {
  43. requestData(method: .get, encoding: encoding, url: url, parames: parames, timeoutInterval: timeoutInterval) { responseObject, error, timeline in
  44. response(responseObject, error, timeline)
  45. }
  46. }
  47. /// post请求
  48. public class func postRequestData(url: String, parames: [String: Any]?, encoding: ParameterEncoding = URLEncoding.default, timeoutInterval: TimeInterval = timeoutInterval, response: @escaping completeHander) {
  49. requestData(method: .post, encoding: encoding, url: url, parames: parames, timeoutInterval: timeoutInterval) { responseObject, error, timeline in
  50. response(responseObject, error, timeline)
  51. }
  52. }
  53. // put请求
  54. public class func putRequestData(url: String, parames: [String: Any]?, encoding: ParameterEncoding = URLEncoding.default, timeoutInterval: TimeInterval = timeoutInterval, response: @escaping completeHander) {
  55. requestData(method: .put, encoding: encoding, url: url, parames: parames, timeoutInterval: timeoutInterval) { responseObject, error, timeline in
  56. response(responseObject, error, timeline)
  57. }
  58. }
  59. /// delete请求
  60. public class func deleteRequestData(url: String, parames: [String: Any]?, encoding: ParameterEncoding = URLEncoding.default, timeoutInterval: TimeInterval = timeoutInterval, response: @escaping completeHander) {
  61. requestData(method: .delete, encoding: encoding, url: url, parames: parames, timeoutInterval: timeoutInterval) { responseObject, error, timeline in
  62. response(responseObject, error, timeline)
  63. }
  64. }
  65. /// head请求
  66. public class func headRequestData(url: String, parames: [String: Any]?, encoding: ParameterEncoding = URLEncoding.default, timeoutInterval: TimeInterval = timeoutInterval, response: @escaping completeHander) {
  67. requestData(method: .head, encoding: encoding, url: url, parames: parames, timeoutInterval: timeoutInterval) { responseObject, error, timeline in
  68. response(responseObject, error, timeline)
  69. }
  70. }
  71. /// 网络请求
  72. fileprivate class func requestData(method: HTTPMethod, encoding: ParameterEncoding, url: String, parames: [String: Any]?, timeoutInterval: TimeInterval = timeoutInterval, response: @escaping completeHander) {
  73. if !bf_validURL(url: url) {
  74. response(nil, PQError(msg: "非法地址", code: 0), nil)
  75. return
  76. }
  77. debugPrint("网络请求-发起:url = \(url),parames = \(parames ?? [:])")
  78. AF.request(url, method: method, parameters: parames, encoding: encoding, headers: nil, requestModifier: { request in
  79. request.timeoutInterval = timeoutInterval
  80. }).validate().responseJSON { jsonResponse in
  81. switch jsonResponse.result {
  82. case .success:
  83. let jsonData: Any = try! JSONSerialization.jsonObject(with: jsonResponse.data!, options: JSONSerialization.ReadingOptions.mutableContainers)
  84. debugPrint("网络请求-成功:url = \(jsonResponse.request?.url?.absoluteString ?? ""),jsonData = \(jsonData)")
  85. response(jsonData, nil, jsonResponse.metrics?.taskInterval.duration)
  86. case .failure:
  87. let code: Int? = jsonResponse.response?.statusCode
  88. response(nil, PQError(msg: (code == -1009 || code == -1001) ? "网络不可用" : jsonResponse.error?.localizedDescription, code: code ?? 10001), jsonResponse.metrics?.taskInterval.duration)
  89. debugPrint("网络请求-失败:url = \(jsonResponse.request?.url?.absoluteString ?? ""),error = \(String(describing: jsonResponse.error))")
  90. }
  91. }
  92. }
  93. /// 取消网络请求
  94. /// - Parameter url: 某一个地址,空则取消所有
  95. /// - Returns: <#description#>
  96. public class func cancelTask(url: String?) {
  97. sessionManager?.session.getAllTasks(completionHandler: { tasks in
  98. tasks.forEach { task in
  99. if task.currentRequest?.url?.absoluteString == url {
  100. task.cancel()
  101. }
  102. }
  103. })
  104. }
  105. public class func bf_validURL(url: String?) -> Bool {
  106. if url == nil || (url?.count ?? 0) <= 4 || (!(url?.hasPrefix("http") ?? false) && !(url?.hasPrefix("https") ?? false)) {
  107. return false
  108. }
  109. return true
  110. }
  111. /// 获取网络状态
  112. /// - Returns: <#description#>
  113. public class func networkStatusDescription() -> String {
  114. let status = NetworkReachabilityManager(host: "www.baidu.com")?.status
  115. var statusStr: String!
  116. switch status {
  117. case .unknown:
  118. statusStr = "NETWORK_UNKNOWN"
  119. case .notReachable:
  120. statusStr = "NETWORK_NO"
  121. case .reachable(.cellular):
  122. statusStr = "4G/5G"
  123. case .reachable(.ethernetOrWiFi):
  124. statusStr = "Wi-Fi"
  125. default:
  126. statusStr = "NETWORK_UNKNOWN"
  127. }
  128. return statusStr
  129. }
  130. /// 判断是否有网
  131. /// - Returns: <#description#>
  132. public class func isNetReachabled() -> Bool {
  133. return NetworkReachabilityManager(host: "www.baidu.com")?.status == .reachable(.cellular) || NetworkReachabilityManager(host: "www.baidu.com")?.status == .reachable(.ethernetOrWiFi)
  134. }
  135. /// 获取ip地址
  136. /// - Returns: <#description#>
  137. public class func ipAddressDescription() -> String {
  138. var addresses = [String]()
  139. var ifaddr: UnsafeMutablePointer<ifaddrs>?
  140. if getifaddrs(&ifaddr) == 0 {
  141. var ptr = ifaddr
  142. while ptr != nil {
  143. let flags = Int32(ptr!.pointee.ifa_flags)
  144. var addr = ptr!.pointee.ifa_addr.pointee
  145. if (flags & (IFF_UP | IFF_RUNNING | IFF_LOOPBACK)) == (IFF_UP | IFF_RUNNING) {
  146. if addr.sa_family == UInt8(AF_INET) || addr.sa_family == UInt8(AF_INET6) {
  147. var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
  148. if getnameinfo(&addr, socklen_t(addr.sa_len), &hostname, socklen_t(hostname.count), nil, socklen_t(0), NI_NUMERICHOST) == 0 {
  149. if let address = String(validatingUTF8: hostname) {
  150. addresses.append(address)
  151. }
  152. }
  153. }
  154. }
  155. ptr = ptr!.pointee.ifa_next
  156. }
  157. freeifaddrs(ifaddr)
  158. }
  159. return addresses.first ?? "0.0.0.0"
  160. }
  161. // 将原始的url编码为合法的url
  162. public class func bf_urlEncoded(url: String) -> String {
  163. let encodeUrlString = url.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
  164. return encodeUrlString ?? ""
  165. }
  166. // 将编码后的url转换回原始的url
  167. public class func bf_urlDecoded(url: String) -> String {
  168. return url.removingPercentEncoding ?? ""
  169. }
  170. }