Moya+Alamofire.swift 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import Foundation
  2. import Alamofire
  3. public typealias Session = Alamofire.Session
  4. internal typealias Request = Alamofire.Request
  5. internal typealias DownloadRequest = Alamofire.DownloadRequest
  6. internal typealias UploadRequest = Alamofire.UploadRequest
  7. internal typealias DataRequest = Alamofire.DataRequest
  8. internal typealias URLRequestConvertible = Alamofire.URLRequestConvertible
  9. /// Represents an HTTP method.
  10. public typealias Method = Alamofire.HTTPMethod
  11. /// Choice of parameter encoding.
  12. public typealias ParameterEncoding = Alamofire.ParameterEncoding
  13. public typealias JSONEncoding = Alamofire.JSONEncoding
  14. public typealias URLEncoding = Alamofire.URLEncoding
  15. /// Multipart form.
  16. public typealias RequestMultipartFormData = Alamofire.MultipartFormData
  17. /// Multipart form data encoding result.
  18. public typealias DownloadDestination = Alamofire.DownloadRequest.Destination
  19. /// Make the Alamofire Request type conform to our type, to prevent leaking Alamofire to plugins.
  20. extension Request: RequestType {
  21. public var sessionHeaders: [String: String] {
  22. return delegate?.sessionConfiguration.httpAdditionalHeaders as? [String: String] ?? [:]
  23. }
  24. }
  25. /// Represents Request interceptor type that can modify/act on Request
  26. public typealias RequestInterceptor = Alamofire.RequestInterceptor
  27. /// Internal token that can be used to cancel requests
  28. public final class CancellableToken: Cancellable, CustomDebugStringConvertible {
  29. let cancelAction: () -> Void
  30. let request: Request?
  31. public fileprivate(set) var isCancelled = false
  32. fileprivate var lock: DispatchSemaphore = DispatchSemaphore(value: 1)
  33. public func cancel() {
  34. _ = lock.wait(timeout: DispatchTime.distantFuture)
  35. defer { lock.signal() }
  36. guard !isCancelled else { return }
  37. isCancelled = true
  38. cancelAction()
  39. }
  40. public init(action: @escaping () -> Void) {
  41. self.cancelAction = action
  42. self.request = nil
  43. }
  44. init(request: Request) {
  45. self.request = request
  46. self.cancelAction = {
  47. request.cancel()
  48. }
  49. }
  50. /// A textual representation of this instance, suitable for debugging.
  51. public var debugDescription: String {
  52. guard let request = self.request else {
  53. return "Empty Request"
  54. }
  55. return request.cURLDescription()
  56. }
  57. }
  58. internal typealias RequestableCompletion = (HTTPURLResponse?, URLRequest?, Data?, Swift.Error?) -> Void
  59. internal protocol Requestable {
  60. func response(callbackQueue: DispatchQueue?, completionHandler: @escaping RequestableCompletion) -> Self
  61. }
  62. extension DataRequest: Requestable {
  63. internal func response(callbackQueue: DispatchQueue?, completionHandler: @escaping RequestableCompletion) -> Self {
  64. if let callbackQueue = callbackQueue {
  65. return response(queue: callbackQueue) { handler in
  66. completionHandler(handler.response, handler.request, handler.data, handler.error)
  67. }
  68. } else {
  69. return response { handler in
  70. completionHandler(handler.response, handler.request, handler.data, handler.error)
  71. }
  72. }
  73. }
  74. }
  75. extension DownloadRequest: Requestable {
  76. internal func response(callbackQueue: DispatchQueue?, completionHandler: @escaping RequestableCompletion) -> Self {
  77. if let callbackQueue = callbackQueue {
  78. return response(queue: callbackQueue) { handler in
  79. completionHandler(handler.response, handler.request, nil, handler.error)
  80. }
  81. } else {
  82. return response { handler in
  83. completionHandler(handler.response, handler.request, nil, handler.error)
  84. }
  85. }
  86. }
  87. }
  88. final class MoyaRequestInterceptor: RequestInterceptor {
  89. private let lock: NSRecursiveLock = NSRecursiveLock()
  90. var prepare: ((URLRequest) -> URLRequest)?
  91. private var internalWillSend: ((URLRequest) -> Void)?
  92. var willSend: ((URLRequest) -> Void)? {
  93. get {
  94. lock.lock(); defer { lock.unlock() }
  95. return internalWillSend
  96. }
  97. set {
  98. lock.lock(); defer { lock.unlock() }
  99. internalWillSend = newValue
  100. }
  101. }
  102. init(prepare: ((URLRequest) -> URLRequest)? = nil, willSend: ((URLRequest) -> Void)? = nil) {
  103. self.prepare = prepare
  104. self.willSend = willSend
  105. }
  106. func adapt(_ urlRequest: URLRequest, for session: Alamofire.Session, completion: @escaping (Result<URLRequest, Error>) -> Void) {
  107. let request = prepare?(urlRequest) ?? urlRequest
  108. willSend?(request)
  109. completion(.success(request))
  110. }
  111. }