Response.swift 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. //
  2. // Response.swift
  3. //
  4. // Copyright (c) 2014-2018 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 a serialized response of a data or upload request.
  26. public struct DataResponse<Value> {
  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 result of response serialization.
  34. public let result: Result<Value>
  35. /// The final metrics of a response.
  36. public let metrics: URLSessionTaskMetrics?
  37. /// The timeline of the complete lifecycle of the request.
  38. // public let timeline: Timeline
  39. /// Returns the associated value of the result if it is a success, `nil` otherwise.
  40. public var value: Value? { return result.value }
  41. /// Returns the associated error value if the result if it is a failure, `nil` otherwise.
  42. public var error: Error? { return result.error }
  43. /// Creates a `DataResponse` instance with the specified parameters derived from response serialization.
  44. ///
  45. /// - parameter request: The URL request sent to the server.
  46. /// - parameter response: The server's response to the URL request.
  47. /// - parameter data: The data returned by the server.
  48. /// - parameter result: The result of response serialization.
  49. /// - parameter timeline: The timeline of the complete lifecycle of the `Request`. Defaults to `Timeline()`.
  50. ///
  51. /// - returns: The new `DataResponse` instance.
  52. public init(request: URLRequest?,
  53. response: HTTPURLResponse?,
  54. data: Data?,
  55. metrics: URLSessionTaskMetrics?,
  56. result: Result<Value>) {
  57. self.request = request
  58. self.response = response
  59. self.data = data
  60. self.metrics = metrics
  61. self.result = result
  62. }
  63. }
  64. extension DataResponse {
  65. /// Evaluates the specified closure when the result of this `DataResponse` is a success, passing the unwrapped
  66. /// result value as a parameter.
  67. ///
  68. /// Use the `map` method with a closure that does not throw. For example:
  69. ///
  70. /// let possibleData: DataResponse<Data> = ...
  71. /// let possibleInt = possibleData.map { $0.count }
  72. ///
  73. /// - parameter transform: A closure that takes the success value of the instance's result.
  74. ///
  75. /// - returns: A `DataResponse` whose result wraps the value returned by the given closure. If this instance's
  76. /// result is a failure, returns a response wrapping the same failure.
  77. public func map<T>(_ transform: (Value) -> T) -> DataResponse<T> {
  78. return DataResponse<T>(request: request,
  79. response: self.response,
  80. data: data,
  81. metrics: metrics,
  82. result: result.map(transform))
  83. }
  84. /// Evaluates the given closure when the result of this `DataResponse` is a success, passing the unwrapped result
  85. /// value as a parameter.
  86. ///
  87. /// Use the `flatMap` method with a closure that may throw an error. For example:
  88. ///
  89. /// let possibleData: DataResponse<Data> = ...
  90. /// let possibleObject = possibleData.flatMap {
  91. /// try JSONSerialization.jsonObject(with: $0)
  92. /// }
  93. ///
  94. /// - parameter transform: A closure that takes the success value of the instance's result.
  95. ///
  96. /// - returns: A success or failure `DataResponse` depending on the result of the given closure. If this instance's
  97. /// result is a failure, returns the same failure.
  98. public func flatMap<T>(_ transform: (Value) throws -> T) -> DataResponse<T> {
  99. return DataResponse<T>(request: request,
  100. response: self.response,
  101. data: data,
  102. metrics: metrics,
  103. result: result.flatMap(transform))
  104. }
  105. /// Evaluates the specified closure when the `DataResponse` is a failure, passing the unwrapped error as a parameter.
  106. ///
  107. /// Use the `mapError` function with a closure that does not throw. For example:
  108. ///
  109. /// let possibleData: DataResponse<Data> = ...
  110. /// let withMyError = possibleData.mapError { MyError.error($0) }
  111. ///
  112. /// - Parameter transform: A closure that takes the error of the instance.
  113. /// - Returns: A `DataResponse` instance containing the result of the transform.
  114. public func mapError<E: Error>(_ transform: (Error) -> E) -> DataResponse {
  115. return DataResponse(request: request,
  116. response: self.response,
  117. data: data,
  118. metrics: metrics,
  119. result: result.mapError(transform))
  120. }
  121. /// Evaluates the specified closure when the `DataResponse` is a failure, passing the unwrapped error as a parameter.
  122. ///
  123. /// Use the `flatMapError` function with a closure that may throw an error. For example:
  124. ///
  125. /// let possibleData: DataResponse<Data> = ...
  126. /// let possibleObject = possibleData.flatMapError {
  127. /// try someFailableFunction(taking: $0)
  128. /// }
  129. ///
  130. /// - Parameter transform: A throwing closure that takes the error of the instance.
  131. ///
  132. /// - Returns: A `DataResponse` instance containing the result of the transform.
  133. public func flatMapError<E: Error>(_ transform: (Error) throws -> E) -> DataResponse {
  134. return DataResponse(request: request,
  135. response: self.response,
  136. data: data,
  137. metrics: metrics,
  138. result: result.flatMapError(transform))
  139. }
  140. }
  141. // MARK: -
  142. /// Used to store all data associated with a serialized response of a download request.
  143. public struct DownloadResponse<Value> {
  144. /// The URL request sent to the server.
  145. public let request: URLRequest?
  146. /// The server's response to the URL request.
  147. public let response: HTTPURLResponse?
  148. /// The temporary destination URL of the data returned from the server.
  149. public let temporaryURL: URL?
  150. /// The final destination URL of the data returned from the server if it was moved.
  151. public let destinationURL: URL?
  152. /// The resume data generated if the request was cancelled.
  153. public let resumeData: Data?
  154. /// The result of response serialization.
  155. public let result: Result<Value>
  156. /// The timeline of the complete lifecycle of the request.
  157. // public let timeline: Timeline
  158. public let metrics: URLSessionTaskMetrics?
  159. /// Returns the associated value of the result if it is a success, `nil` otherwise.
  160. public var value: Value? { return result.value }
  161. /// Returns the associated error value if the result if it is a failure, `nil` otherwise.
  162. public var error: Error? { return result.error }
  163. // var _metrics: AnyObject?
  164. /// Creates a `DownloadResponse` instance with the specified parameters derived from response serialization.
  165. ///
  166. /// - parameter request: The URL request sent to the server.
  167. /// - parameter response: The server's response to the URL request.
  168. /// - parameter temporaryURL: The temporary destination URL of the data returned from the server.
  169. /// - parameter destinationURL: The final destination URL of the data returned from the server if it was moved.
  170. /// - parameter resumeData: The resume data generated if the request was cancelled.
  171. /// - parameter result: The result of response serialization.
  172. /// - parameter timeline: The timeline of the complete lifecycle of the `Request`. Defaults to `Timeline()`.
  173. ///
  174. /// - returns: The new `DownloadResponse` instance.
  175. public init(
  176. request: URLRequest?,
  177. response: HTTPURLResponse?,
  178. temporaryURL: URL?,
  179. destinationURL: URL?,
  180. resumeData: Data?,
  181. metrics: URLSessionTaskMetrics?,
  182. result: Result<Value>)
  183. {
  184. self.request = request
  185. self.response = response
  186. self.temporaryURL = temporaryURL
  187. self.destinationURL = destinationURL
  188. self.resumeData = resumeData
  189. self.metrics = metrics
  190. self.result = result
  191. // self.timeline = timeline
  192. }
  193. }