Response.swift 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  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. init(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?, timeline: Timeline = Timeline()) {
  39. self.request = request
  40. self.response = response
  41. self.data = data
  42. self.error = error
  43. self.timeline = timeline
  44. }
  45. }
  46. // MARK: -
  47. /// Used to store all data associated with a serialized response of a data or upload request.
  48. public struct DataResponse<Value> {
  49. /// The URL request sent to the server.
  50. public let request: URLRequest?
  51. /// The server's response to the URL request.
  52. public let response: HTTPURLResponse?
  53. /// The data returned by the server.
  54. public let data: Data?
  55. /// The result of response serialization.
  56. public let result: Result<Value>
  57. /// The timeline of the complete lifecycle of the request.
  58. public let timeline: Timeline
  59. var _metrics: AnyObject?
  60. /// Creates a `DataResponse` instance with the specified parameters derived from response serialization.
  61. ///
  62. /// - parameter request: The URL request sent to the server.
  63. /// - parameter response: The server's response to the URL request.
  64. /// - parameter data: The data returned by the server.
  65. /// - parameter result: The result of response serialization.
  66. /// - parameter timeline: The timeline of the complete lifecycle of the `Request`. Defaults to `Timeline()`.
  67. ///
  68. /// - returns: The new `DataResponse` instance.
  69. public init(
  70. request: URLRequest?,
  71. response: HTTPURLResponse?,
  72. data: Data?,
  73. result: Result<Value>,
  74. timeline: Timeline = Timeline())
  75. {
  76. self.request = request
  77. self.response = response
  78. self.data = data
  79. self.result = result
  80. self.timeline = timeline
  81. }
  82. }
  83. // MARK: -
  84. extension DataResponse: CustomStringConvertible, CustomDebugStringConvertible {
  85. /// The textual representation used when written to an output stream, which includes whether the result was a
  86. /// success or failure.
  87. public var description: String {
  88. return result.debugDescription
  89. }
  90. /// The debug textual representation used when written to an output stream, which includes the URL request, the URL
  91. /// response, the server data, the response serialization result and the timeline.
  92. public var debugDescription: String {
  93. var output: [String] = []
  94. output.append(request != nil ? "[Request]: \(request!)" : "[Request]: nil")
  95. output.append(response != nil ? "[Response]: \(response!)" : "[Response]: nil")
  96. output.append("[Data]: \(data?.count ?? 0) bytes")
  97. output.append("[Result]: \(result.debugDescription)")
  98. output.append("[Timeline]: \(timeline.debugDescription)")
  99. return output.joined(separator: "\n")
  100. }
  101. }
  102. // MARK: -
  103. /// Used to store all data associated with an non-serialized response of a download request.
  104. public struct DefaultDownloadResponse {
  105. /// The URL request sent to the server.
  106. public let request: URLRequest?
  107. /// The server's response to the URL request.
  108. public let response: HTTPURLResponse?
  109. /// The temporary destination URL of the data returned from the server.
  110. public let temporaryURL: URL?
  111. /// The final destination URL of the data returned from the server if it was moved.
  112. public let destinationURL: URL?
  113. /// The resume data generated if the request was cancelled.
  114. public let resumeData: Data?
  115. /// The error encountered while executing or validating the request.
  116. public let error: Error?
  117. /// The timeline of the complete lifecycle of the request.
  118. public let timeline: Timeline
  119. var _metrics: AnyObject?
  120. init(
  121. request: URLRequest?,
  122. response: HTTPURLResponse?,
  123. temporaryURL: URL?,
  124. destinationURL: URL?,
  125. resumeData: Data?,
  126. error: Error?,
  127. timeline: Timeline = Timeline())
  128. {
  129. self.request = request
  130. self.response = response
  131. self.temporaryURL = temporaryURL
  132. self.destinationURL = destinationURL
  133. self.resumeData = resumeData
  134. self.error = error
  135. self.timeline = timeline
  136. }
  137. }
  138. // MARK: -
  139. /// Used to store all data associated with a serialized response of a download request.
  140. public struct DownloadResponse<Value> {
  141. /// The URL request sent to the server.
  142. public let request: URLRequest?
  143. /// The server's response to the URL request.
  144. public let response: HTTPURLResponse?
  145. /// The temporary destination URL of the data returned from the server.
  146. public let temporaryURL: URL?
  147. /// The final destination URL of the data returned from the server if it was moved.
  148. public let destinationURL: URL?
  149. /// The resume data generated if the request was cancelled.
  150. public let resumeData: Data?
  151. /// The result of response serialization.
  152. public let result: Result<Value>
  153. /// The timeline of the complete lifecycle of the request.
  154. public let timeline: Timeline
  155. var _metrics: AnyObject?
  156. /// Creates a `DownloadResponse` instance with the specified parameters derived from response serialization.
  157. ///
  158. /// - parameter request: The URL request sent to the server.
  159. /// - parameter response: The server's response to the URL request.
  160. /// - parameter temporaryURL: The temporary destination URL of the data returned from the server.
  161. /// - parameter destinationURL: The final destination URL of the data returned from the server if it was moved.
  162. /// - parameter resumeData: The resume data generated if the request was cancelled.
  163. /// - parameter result: The result of response serialization.
  164. /// - parameter timeline: The timeline of the complete lifecycle of the `Request`. Defaults to `Timeline()`.
  165. ///
  166. /// - returns: The new `DownloadResponse` instance.
  167. public init(
  168. request: URLRequest?,
  169. response: HTTPURLResponse?,
  170. temporaryURL: URL?,
  171. destinationURL: URL?,
  172. resumeData: Data?,
  173. result: Result<Value>,
  174. timeline: Timeline = Timeline())
  175. {
  176. self.request = request
  177. self.response = response
  178. self.temporaryURL = temporaryURL
  179. self.destinationURL = destinationURL
  180. self.resumeData = resumeData
  181. self.result = result
  182. self.timeline = timeline
  183. }
  184. }
  185. // MARK: -
  186. extension DownloadResponse: CustomStringConvertible, CustomDebugStringConvertible {
  187. /// The textual representation used when written to an output stream, which includes whether the result was a
  188. /// success or failure.
  189. public var description: String {
  190. return result.debugDescription
  191. }
  192. /// The debug textual representation used when written to an output stream, which includes the URL request, the URL
  193. /// response, the temporary and destination URLs, the resume data, the response serialization result and the
  194. /// timeline.
  195. public var debugDescription: String {
  196. var output: [String] = []
  197. output.append(request != nil ? "[Request]: \(request!)" : "[Request]: nil")
  198. output.append(response != nil ? "[Response]: \(response!)" : "[Response]: nil")
  199. output.append("[TemporaryURL]: \(temporaryURL?.path ?? "nil")")
  200. output.append("[DestinationURL]: \(destinationURL?.path ?? "nil")")
  201. output.append("[ResumeData]: \(resumeData?.count ?? 0) bytes")
  202. output.append("[Result]: \(result.debugDescription)")
  203. output.append("[Timeline]: \(timeline.debugDescription)")
  204. return output.joined(separator: "\n")
  205. }
  206. }
  207. // MARK: -
  208. protocol Response {
  209. /// The task metrics containing the request / response statistics.
  210. var _metrics: AnyObject? { get set }
  211. mutating func add(_ metrics: AnyObject?)
  212. }
  213. extension Response {
  214. mutating func add(_ metrics: AnyObject?) {
  215. #if !os(watchOS)
  216. guard #available(iOS 10.0, macOS 10.12, tvOS 10.0, *) else { return }
  217. guard let metrics = metrics as? URLSessionTaskMetrics else { return }
  218. _metrics = metrics
  219. #endif
  220. }
  221. }
  222. // MARK: -
  223. @available(iOS 10.0, macOS 10.12, tvOS 10.0, *)
  224. extension DefaultDataResponse: Response {
  225. #if !os(watchOS)
  226. /// The task metrics containing the request / response statistics.
  227. public var metrics: URLSessionTaskMetrics? { return _metrics as? URLSessionTaskMetrics }
  228. #endif
  229. }
  230. @available(iOS 10.0, macOS 10.12, tvOS 10.0, *)
  231. extension DataResponse: Response {
  232. #if !os(watchOS)
  233. /// The task metrics containing the request / response statistics.
  234. public var metrics: URLSessionTaskMetrics? { return _metrics as? URLSessionTaskMetrics }
  235. #endif
  236. }
  237. @available(iOS 10.0, macOS 10.12, tvOS 10.0, *)
  238. extension DefaultDownloadResponse: Response {
  239. #if !os(watchOS)
  240. /// The task metrics containing the request / response statistics.
  241. public var metrics: URLSessionTaskMetrics? { return _metrics as? URLSessionTaskMetrics }
  242. #endif
  243. }
  244. @available(iOS 10.0, macOS 10.12, tvOS 10.0, *)
  245. extension DownloadResponse: Response {
  246. #if !os(watchOS)
  247. /// The task metrics containing the request / response statistics.
  248. public var metrics: URLSessionTaskMetrics? { return _metrics as? URLSessionTaskMetrics }
  249. #endif
  250. }