Response.swift 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. //
  2. // Response.swift
  3. //
  4. // Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
  5. //
  6. // Permission is hereby granted, free of charge, to any person obtaining a copy
  7. // of this software and associated documentation files (the "Software"), to deal
  8. // in the Software without restriction, including without limitation the rights
  9. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. // copies of the Software, and to permit persons to whom the Software is
  11. // furnished to do so, subject to the following conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be included in
  14. // all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. // THE SOFTWARE.
  23. //
  24. import Foundation
  25. /// Used to store all data associated with an non-serialized response of a data or upload request.
  26. public struct DefaultDataResponse {
  27. /// The URL request sent to the server.
  28. public let request: URLRequest?
  29. /// The server's response to the URL request.
  30. public let response: HTTPURLResponse?
  31. /// The data returned by the server.
  32. public let data: Data?
  33. /// The error encountered while executing or validating the request.
  34. public let error: Error?
  35. /// The timeline of the complete lifecycle of the request.
  36. public let timeline: Timeline
  37. var _metrics: AnyObject?
  38. /// Creates a `DefaultDataResponse` instance from the specified parameters.
  39. ///
  40. /// - Parameters:
  41. /// - request: The URL request sent to the server.
  42. /// - response: The server's response to the URL request.
  43. /// - data: The data returned by the server.
  44. /// - error: The error encountered while executing or validating the request.
  45. /// - timeline: The timeline of the complete lifecycle of the request. `Timeline()` by default.
  46. /// - metrics: The task metrics containing the request / response statistics. `nil` by default.
  47. public init(
  48. request: URLRequest?,
  49. response: HTTPURLResponse?,
  50. data: Data?,
  51. error: Error?,
  52. timeline: Timeline = Timeline(),
  53. metrics: AnyObject? = nil)
  54. {
  55. self.request = request
  56. self.response = response
  57. self.data = data
  58. self.error = error
  59. self.timeline = timeline
  60. }
  61. }
  62. // MARK: -
  63. /// Used to store all data associated with a serialized response of a data or upload request.
  64. public struct DataResponse<Value> {
  65. /// The URL request sent to the server.
  66. public let request: URLRequest?
  67. /// The server's response to the URL request.
  68. public let response: HTTPURLResponse?
  69. /// The data returned by the server.
  70. public let data: Data?
  71. /// The result of response serialization.
  72. public let result: Result<Value>
  73. /// The timeline of the complete lifecycle of the request.
  74. public let timeline: Timeline
  75. var _metrics: AnyObject?
  76. /// Creates a `DataResponse` instance with the specified parameters derived from response serialization.
  77. ///
  78. /// - parameter request: The URL request sent to the server.
  79. /// - parameter response: The server's response to the URL request.
  80. /// - parameter data: The data returned by the server.
  81. /// - parameter result: The result of response serialization.
  82. /// - parameter timeline: The timeline of the complete lifecycle of the `Request`. Defaults to `Timeline()`.
  83. ///
  84. /// - returns: The new `DataResponse` instance.
  85. public init(
  86. request: URLRequest?,
  87. response: HTTPURLResponse?,
  88. data: Data?,
  89. result: Result<Value>,
  90. timeline: Timeline = Timeline())
  91. {
  92. self.request = request
  93. self.response = response
  94. self.data = data
  95. self.result = result
  96. self.timeline = timeline
  97. }
  98. }
  99. // MARK: -
  100. extension DataResponse: CustomStringConvertible, CustomDebugStringConvertible {
  101. /// The textual representation used when written to an output stream, which includes whether the result was a
  102. /// success or failure.
  103. public var description: String {
  104. return result.debugDescription
  105. }
  106. /// The debug textual representation used when written to an output stream, which includes the URL request, the URL
  107. /// response, the server data, the response serialization result and the timeline.
  108. public var debugDescription: String {
  109. var output: [String] = []
  110. output.append(request != nil ? "[Request]: \(request!)" : "[Request]: nil")
  111. output.append(response != nil ? "[Response]: \(response!)" : "[Response]: nil")
  112. output.append("[Data]: \(data?.count ?? 0) bytes")
  113. output.append("[Result]: \(result.debugDescription)")
  114. output.append("[Timeline]: \(timeline.debugDescription)")
  115. return output.joined(separator: "\n")
  116. }
  117. }
  118. // MARK: -
  119. /// Used to store all data associated with an non-serialized response of a download request.
  120. public struct DefaultDownloadResponse {
  121. /// The URL request sent to the server.
  122. public let request: URLRequest?
  123. /// The server's response to the URL request.
  124. public let response: HTTPURLResponse?
  125. /// The temporary destination URL of the data returned from the server.
  126. public let temporaryURL: URL?
  127. /// The final destination URL of the data returned from the server if it was moved.
  128. public let destinationURL: URL?
  129. /// The resume data generated if the request was cancelled.
  130. public let resumeData: Data?
  131. /// The error encountered while executing or validating the request.
  132. public let error: Error?
  133. /// The timeline of the complete lifecycle of the request.
  134. public let timeline: Timeline
  135. var _metrics: AnyObject?
  136. /// Creates a `DefaultDownloadResponse` instance from the specified parameters.
  137. ///
  138. /// - Parameters:
  139. /// - request: The URL request sent to the server.
  140. /// - response: The server's response to the URL request.
  141. /// - temporaryURL: The temporary destination URL of the data returned from the server.
  142. /// - destinationURL: The final destination URL of the data returned from the server if it was moved.
  143. /// - resumeData: The resume data generated if the request was cancelled.
  144. /// - error: The error encountered while executing or validating the request.
  145. /// - timeline: The timeline of the complete lifecycle of the request. `Timeline()` by default.
  146. /// - metrics: The task metrics containing the request / response statistics. `nil` by default.
  147. public init(
  148. request: URLRequest?,
  149. response: HTTPURLResponse?,
  150. temporaryURL: URL?,
  151. destinationURL: URL?,
  152. resumeData: Data?,
  153. error: Error?,
  154. timeline: Timeline = Timeline(),
  155. metrics: AnyObject? = nil)
  156. {
  157. self.request = request
  158. self.response = response
  159. self.temporaryURL = temporaryURL
  160. self.destinationURL = destinationURL
  161. self.resumeData = resumeData
  162. self.error = error
  163. self.timeline = timeline
  164. }
  165. }
  166. // MARK: -
  167. /// Used to store all data associated with a serialized response of a download request.
  168. public struct DownloadResponse<Value> {
  169. /// The URL request sent to the server.
  170. public let request: URLRequest?
  171. /// The server's response to the URL request.
  172. public let response: HTTPURLResponse?
  173. /// The temporary destination URL of the data returned from the server.
  174. public let temporaryURL: URL?
  175. /// The final destination URL of the data returned from the server if it was moved.
  176. public let destinationURL: URL?
  177. /// The resume data generated if the request was cancelled.
  178. public let resumeData: Data?
  179. /// The result of response serialization.
  180. public let result: Result<Value>
  181. /// The timeline of the complete lifecycle of the request.
  182. public let timeline: Timeline
  183. var _metrics: AnyObject?
  184. /// Creates a `DownloadResponse` instance with the specified parameters derived from response serialization.
  185. ///
  186. /// - parameter request: The URL request sent to the server.
  187. /// - parameter response: The server's response to the URL request.
  188. /// - parameter temporaryURL: The temporary destination URL of the data returned from the server.
  189. /// - parameter destinationURL: The final destination URL of the data returned from the server if it was moved.
  190. /// - parameter resumeData: The resume data generated if the request was cancelled.
  191. /// - parameter result: The result of response serialization.
  192. /// - parameter timeline: The timeline of the complete lifecycle of the `Request`. Defaults to `Timeline()`.
  193. ///
  194. /// - returns: The new `DownloadResponse` instance.
  195. public init(
  196. request: URLRequest?,
  197. response: HTTPURLResponse?,
  198. temporaryURL: URL?,
  199. destinationURL: URL?,
  200. resumeData: Data?,
  201. result: Result<Value>,
  202. timeline: Timeline = Timeline())
  203. {
  204. self.request = request
  205. self.response = response
  206. self.temporaryURL = temporaryURL
  207. self.destinationURL = destinationURL
  208. self.resumeData = resumeData
  209. self.result = result
  210. self.timeline = timeline
  211. }
  212. }
  213. // MARK: -
  214. extension DownloadResponse: CustomStringConvertible, CustomDebugStringConvertible {
  215. /// The textual representation used when written to an output stream, which includes whether the result was a
  216. /// success or failure.
  217. public var description: String {
  218. return result.debugDescription
  219. }
  220. /// The debug textual representation used when written to an output stream, which includes the URL request, the URL
  221. /// response, the temporary and destination URLs, the resume data, the response serialization result and the
  222. /// timeline.
  223. public var debugDescription: String {
  224. var output: [String] = []
  225. output.append(request != nil ? "[Request]: \(request!)" : "[Request]: nil")
  226. output.append(response != nil ? "[Response]: \(response!)" : "[Response]: nil")
  227. output.append("[TemporaryURL]: \(temporaryURL?.path ?? "nil")")
  228. output.append("[DestinationURL]: \(destinationURL?.path ?? "nil")")
  229. output.append("[ResumeData]: \(resumeData?.count ?? 0) bytes")
  230. output.append("[Result]: \(result.debugDescription)")
  231. output.append("[Timeline]: \(timeline.debugDescription)")
  232. return output.joined(separator: "\n")
  233. }
  234. }
  235. // MARK: -
  236. protocol Response {
  237. /// The task metrics containing the request / response statistics.
  238. var _metrics: AnyObject? { get set }
  239. mutating func add(_ metrics: AnyObject?)
  240. }
  241. extension Response {
  242. mutating func add(_ metrics: AnyObject?) {
  243. #if !os(watchOS)
  244. guard #available(iOS 10.0, macOS 10.12, tvOS 10.0, *) else { return }
  245. guard let metrics = metrics as? URLSessionTaskMetrics else { return }
  246. _metrics = metrics
  247. #endif
  248. }
  249. }
  250. // MARK: -
  251. @available(iOS 10.0, macOS 10.12, tvOS 10.0, *)
  252. extension DefaultDataResponse: Response {
  253. #if !os(watchOS)
  254. /// The task metrics containing the request / response statistics.
  255. public var metrics: URLSessionTaskMetrics? { return _metrics as? URLSessionTaskMetrics }
  256. #endif
  257. }
  258. @available(iOS 10.0, macOS 10.12, tvOS 10.0, *)
  259. extension DataResponse: Response {
  260. #if !os(watchOS)
  261. /// The task metrics containing the request / response statistics.
  262. public var metrics: URLSessionTaskMetrics? { return _metrics as? URLSessionTaskMetrics }
  263. #endif
  264. }
  265. @available(iOS 10.0, macOS 10.12, tvOS 10.0, *)
  266. extension DefaultDownloadResponse: Response {
  267. #if !os(watchOS)
  268. /// The task metrics containing the request / response statistics.
  269. public var metrics: URLSessionTaskMetrics? { return _metrics as? URLSessionTaskMetrics }
  270. #endif
  271. }
  272. @available(iOS 10.0, macOS 10.12, tvOS 10.0, *)
  273. extension DownloadResponse: Response {
  274. #if !os(watchOS)
  275. /// The task metrics containing the request / response statistics.
  276. public var metrics: URLSessionTaskMetrics? { return _metrics as? URLSessionTaskMetrics }
  277. #endif
  278. }