2
0

ResponseSerialization.swift 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593
  1. //
  2. // ResponseSerialization.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. // MARK: Protocols
  26. /// The type to which all data response serializers must conform in order to serialize a response.
  27. public protocol DataResponseSerializerProtocol {
  28. /// The type of serialized object to be created by this serializer.
  29. associatedtype SerializedObject
  30. /// The function used to serialize the response data in response handlers.
  31. func serialize(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?) throws -> SerializedObject
  32. }
  33. /// The type to which all download response serializers must conform in order to serialize a response.
  34. public protocol DownloadResponseSerializerProtocol {
  35. /// The type of serialized object to be created by this `DownloadResponseSerializerType`.
  36. associatedtype SerializedObject
  37. /// The function used to serialize the downloaded data in response handlers.
  38. func serializeDownload(request: URLRequest?, response: HTTPURLResponse?, fileURL: URL?, error: Error?) throws -> SerializedObject
  39. }
  40. /// A serializer that can handle both data and download responses.
  41. public protocol ResponseSerializer: DataResponseSerializerProtocol & DownloadResponseSerializerProtocol {
  42. var emptyRequestMethods: Set<HTTPMethod> { get }
  43. var emptyResponseCodes: Set<Int> { get }
  44. }
  45. extension ResponseSerializer {
  46. public static var defaultEmptyRequestMethods: Set<HTTPMethod> { return [.head] }
  47. public static var defaultEmptyResponseCodes: Set<Int> { return [204, 205] }
  48. var emptyRequestMethods: Set<HTTPMethod> { return Self.defaultEmptyRequestMethods }
  49. var emptyResponseCodes: Set<Int> { return Self.defaultEmptyResponseCodes }
  50. public func requestAllowsEmptyResponseData(_ request: URLRequest?) -> Bool? {
  51. return request.flatMap { $0.httpMethod }
  52. .flatMap(HTTPMethod.init)
  53. .map { emptyRequestMethods.contains($0) }
  54. }
  55. public func responseAllowsEmptyResponseData(_ response: HTTPURLResponse?) -> Bool? {
  56. return response.flatMap { $0.statusCode }
  57. .map { emptyResponseCodes.contains($0) }
  58. }
  59. public func emptyResponseAllowed(forRequest request: URLRequest?, response: HTTPURLResponse?) -> Bool {
  60. return requestAllowsEmptyResponseData(request) ?? responseAllowsEmptyResponseData(response) ?? false
  61. }
  62. }
  63. /// By default, any serializer declared to conform to both types will get file serialization for free, as it just feeds
  64. /// the data read from disk into the data response serializer.
  65. public extension DownloadResponseSerializerProtocol where Self: DataResponseSerializerProtocol {
  66. public func serializeDownload(request: URLRequest?, response: HTTPURLResponse?, fileURL: URL?, error: Error?) throws -> Self.SerializedObject {
  67. guard error == nil else { throw error! }
  68. guard let fileURL = fileURL else {
  69. throw AFError.responseSerializationFailed(reason: .inputFileNil)
  70. }
  71. let data: Data
  72. do {
  73. data = try Data(contentsOf: fileURL)
  74. } catch {
  75. throw AFError.responseSerializationFailed(reason: .inputFileReadFailed(at: fileURL))
  76. }
  77. do {
  78. return try serialize(request: request, response: response, data: data, error: error)
  79. } catch {
  80. throw error
  81. }
  82. }
  83. }
  84. // MARK: - Default
  85. extension DataRequest {
  86. /// Adds a handler to be called once the request has finished.
  87. ///
  88. /// - Parameters:
  89. /// - queue: The queue on which the completion handler is dispatched. Defaults to `nil`, which means
  90. /// the handler is called on `.main`.
  91. /// - completionHandler: The code to be executed once the request has finished.
  92. /// - Returns: The request.
  93. @discardableResult
  94. public func response(queue: DispatchQueue? = nil, completionHandler: @escaping (DataResponse<Data?>) -> Void) -> Self {
  95. internalQueue.addOperation {
  96. self.serializationQueue.async {
  97. let result = Result(value: self.data, error: self.error)
  98. let response = DataResponse(request: self.request,
  99. response: self.response,
  100. data: self.data,
  101. metrics: self.metrics,
  102. serializationDuration: 0,
  103. result: result)
  104. self.eventMonitor?.request(self, didParseResponse: response)
  105. (queue ?? .main).async { completionHandler(response) }
  106. }
  107. }
  108. return self
  109. }
  110. /// Adds a handler to be called once the request has finished.
  111. ///
  112. /// - Parameters:
  113. /// - queue: The queue on which the completion handler is dispatched. Defaults to `nil`, which means
  114. /// the handler is called on `.main`.
  115. /// - responseSerializer: The response serializer responsible for serializing the request, response, and data.
  116. /// - completionHandler: The code to be executed once the request has finished.
  117. /// - Returns: The request.
  118. @discardableResult
  119. public func response<Serializer: DataResponseSerializerProtocol>(
  120. queue: DispatchQueue? = nil,
  121. responseSerializer: Serializer,
  122. completionHandler: @escaping (DataResponse<Serializer.SerializedObject>) -> Void)
  123. -> Self
  124. {
  125. internalQueue.addOperation {
  126. self.serializationQueue.async {
  127. let start = CFAbsoluteTimeGetCurrent()
  128. let result = Result { try responseSerializer.serialize(request: self.request,
  129. response: self.response,
  130. data: self.data,
  131. error: self.error) }
  132. let end = CFAbsoluteTimeGetCurrent()
  133. let response = DataResponse(request: self.request,
  134. response: self.response,
  135. data: self.data,
  136. metrics: self.metrics,
  137. serializationDuration: (end - start),
  138. result: result)
  139. self.eventMonitor?.request(self, didParseResponse: response)
  140. (queue ?? .main).async { completionHandler(response) }
  141. }
  142. }
  143. return self
  144. }
  145. }
  146. extension DownloadRequest {
  147. /// Adds a handler to be called once the request has finished.
  148. ///
  149. /// - Parameters:
  150. /// - queue: The queue on which the completion handler is dispatched. Defaults to `nil`, which means
  151. /// the handler is called on `.main`.
  152. /// - completionHandler: The code to be executed once the request has finished.
  153. /// - Returns: The request.
  154. @discardableResult
  155. public func response(
  156. queue: DispatchQueue? = nil,
  157. completionHandler: @escaping (DownloadResponse<URL?>) -> Void)
  158. -> Self
  159. {
  160. internalQueue.addOperation {
  161. self.serializationQueue.async {
  162. let result = Result(value: self.fileURL , error: self.error)
  163. let response = DownloadResponse(request: self.request,
  164. response: self.response,
  165. fileURL: self.fileURL,
  166. resumeData: self.resumeData,
  167. metrics: self.metrics,
  168. serializationDuration: 0,
  169. result: result)
  170. (queue ?? .main).async { completionHandler(response) }
  171. }
  172. }
  173. return self
  174. }
  175. /// Adds a handler to be called once the request has finished.
  176. ///
  177. /// - Parameters:
  178. /// - queue: The queue on which the completion handler is dispatched. Defaults to `nil`, which means
  179. /// the handler is called on `.main`.
  180. /// - responseSerializer: The response serializer responsible for serializing the request, response, and data
  181. /// contained in the destination url.
  182. /// - completionHandler: The code to be executed once the request has finished.
  183. /// - Returns: The request.
  184. @discardableResult
  185. public func response<T: DownloadResponseSerializerProtocol>(
  186. queue: DispatchQueue? = nil,
  187. responseSerializer: T,
  188. completionHandler: @escaping (DownloadResponse<T.SerializedObject>) -> Void)
  189. -> Self
  190. {
  191. internalQueue.addOperation {
  192. self.serializationQueue.async {
  193. let start = CFAbsoluteTimeGetCurrent()
  194. let result = Result { try responseSerializer.serializeDownload(request: self.request,
  195. response: self.response,
  196. fileURL: self.fileURL,
  197. error: self.error) }
  198. let end = CFAbsoluteTimeGetCurrent()
  199. let response = DownloadResponse(request: self.request,
  200. response: self.response,
  201. fileURL: self.fileURL,
  202. resumeData: self.resumeData,
  203. metrics: self.metrics,
  204. serializationDuration: (end - start),
  205. result: result)
  206. (queue ?? .main).async { completionHandler(response) }
  207. }
  208. }
  209. return self
  210. }
  211. }
  212. // MARK: - Data
  213. extension DataRequest {
  214. /// Adds a handler to be called once the request has finished.
  215. ///
  216. /// - Parameters:
  217. /// - queue: The queue on which the completion handler is dispatched. Defaults to `nil`, which means
  218. /// the handler is called on `.main`.
  219. /// - completionHandler: The code to be executed once the request has finished.
  220. /// - Returns: The request.
  221. @discardableResult
  222. public func responseData(
  223. queue: DispatchQueue? = nil,
  224. completionHandler: @escaping (DataResponse<Data>) -> Void)
  225. -> Self
  226. {
  227. return response(queue: queue,
  228. responseSerializer: DataResponseSerializer(),
  229. completionHandler: completionHandler)
  230. }
  231. }
  232. /// A `ResponseSerializer` that performs minimal reponse checking and returns any response data as-is. By default, a
  233. /// request returning `nil` or no data is considered an error. However, if the response is has a status code valid for
  234. /// empty responses (`204`, `205`), then an empty `Data` value is returned.
  235. public final class DataResponseSerializer: ResponseSerializer {
  236. /// HTTP response codes for which empty responses are allowed.
  237. public let emptyResponseCodes: Set<Int>
  238. /// HTTP request methods for which empty responses are allowed.
  239. public let emptyRequestMethods: Set<HTTPMethod>
  240. /// Creates an instance using the provided values.
  241. ///
  242. /// - Parameters:
  243. /// - emptyResponseCodes: The HTTP response codes for which empty responses are allowed. Defaults to
  244. /// `[204, 205]`.
  245. /// - emptyRequestMethods: The HTTP request methods for which empty responses are allowed. Defaults to `[.head]`.
  246. public init(emptyResponseCodes: Set<Int> = DataResponseSerializer.defaultEmptyResponseCodes,
  247. emptyRequestMethods: Set<HTTPMethod> = DataResponseSerializer.defaultEmptyRequestMethods) {
  248. self.emptyResponseCodes = emptyResponseCodes
  249. self.emptyRequestMethods = emptyRequestMethods
  250. }
  251. public func serialize(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?) throws -> Data {
  252. guard error == nil else { throw error! }
  253. guard let data = data, !data.isEmpty else {
  254. guard emptyResponseAllowed(forRequest: request, response: response) else {
  255. throw AFError.responseSerializationFailed(reason: .inputDataNilOrZeroLength)
  256. }
  257. return Data()
  258. }
  259. return data
  260. }
  261. }
  262. extension DownloadRequest {
  263. /// Adds a handler to be called once the request has finished.
  264. ///
  265. /// - Parameters:
  266. /// - queue: The queue on which the completion handler is dispatched. Defaults to `nil`, which means
  267. /// the handler is called on `.main`.
  268. /// - completionHandler: The code to be executed once the request has finished.
  269. /// - Returns: The request.
  270. @discardableResult
  271. public func responseData(
  272. queue: DispatchQueue? = nil,
  273. completionHandler: @escaping (DownloadResponse<Data>) -> Void)
  274. -> Self
  275. {
  276. return response(
  277. queue: queue,
  278. responseSerializer: DataResponseSerializer(),
  279. completionHandler: completionHandler
  280. )
  281. }
  282. }
  283. // MARK: - String
  284. /// A `ResponseSerializer` that decodes the response data as a `String`. By default, a request returning `nil` or no
  285. /// data is considered an error. However, if the response is has a status code valid for empty responses (`204`, `205`),
  286. /// then an empty `String` is returned.
  287. public final class StringResponseSerializer: ResponseSerializer {
  288. /// Optional string encoding used to validate the response.
  289. public let encoding: String.Encoding?
  290. /// HTTP response codes for which empty responses are allowed.
  291. public let emptyResponseCodes: Set<Int>
  292. /// HTTP request methods for which empty responses are allowed.
  293. public let emptyRequestMethods: Set<HTTPMethod>
  294. /// Creates an instance with the provided values.
  295. ///
  296. /// - Parameters:
  297. /// - encoding: A string encoding. Defaults to `nil`, in which case the encoding will be determined
  298. /// from the server response, falling back to the default HTTP character set, `ISO-8859-1`.
  299. /// - emptyResponseCodes: The HTTP response codes for which empty responses are allowed. Defaults to
  300. /// `[204, 205]`.
  301. /// - emptyRequestMethods: The HTTP request methods for which empty responses are allowed. Defaults to `[.head]`.
  302. public init(encoding: String.Encoding? = nil,
  303. emptyResponseCodes: Set<Int> = StringResponseSerializer.defaultEmptyResponseCodes,
  304. emptyRequestMethods: Set<HTTPMethod> = StringResponseSerializer.defaultEmptyRequestMethods) {
  305. self.encoding = encoding
  306. self.emptyResponseCodes = emptyResponseCodes
  307. self.emptyRequestMethods = emptyRequestMethods
  308. }
  309. public func serialize(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?) throws -> String {
  310. guard error == nil else { throw error! }
  311. guard let data = data, !data.isEmpty else {
  312. guard emptyResponseAllowed(forRequest: request, response: response) else {
  313. throw AFError.responseSerializationFailed(reason: .inputDataNilOrZeroLength)
  314. }
  315. return ""
  316. }
  317. var convertedEncoding = encoding
  318. if let encodingName = response?.textEncodingName as CFString?, convertedEncoding == nil {
  319. let ianaCharSet = CFStringConvertIANACharSetNameToEncoding(encodingName)
  320. let nsStringEncoding = CFStringConvertEncodingToNSStringEncoding(ianaCharSet)
  321. convertedEncoding = String.Encoding(rawValue: nsStringEncoding)
  322. }
  323. let actualEncoding = convertedEncoding ?? .isoLatin1
  324. guard let string = String(data: data, encoding: actualEncoding) else {
  325. throw AFError.responseSerializationFailed(reason: .stringSerializationFailed(encoding: actualEncoding))
  326. }
  327. return string
  328. }
  329. }
  330. extension DataRequest {
  331. /// Adds a handler to be called once the request has finished.
  332. ///
  333. /// - Parameters:
  334. /// - queue: The queue on which the completion handler is dispatched. Defaults to `nil`, which means
  335. /// the handler is called on `.main`.
  336. /// - encoding: The string encoding. Defaults to `nil`, in which case the encoding will be determined from
  337. /// the server response, falling back to the default HTTP character set, `ISO-8859-1`.
  338. /// - completionHandler: A closure to be executed once the request has finished.
  339. /// - Returns: The request.
  340. @discardableResult
  341. public func responseString(queue: DispatchQueue? = nil,
  342. encoding: String.Encoding? = nil,
  343. completionHandler: @escaping (DataResponse<String>) -> Void) -> Self {
  344. return response(queue: queue,
  345. responseSerializer: StringResponseSerializer(encoding: encoding),
  346. completionHandler: completionHandler)
  347. }
  348. }
  349. extension DownloadRequest {
  350. /// Adds a handler to be called once the request has finished.
  351. ///
  352. /// - Parameters:
  353. /// - queue: The queue on which the completion handler is dispatched. Defaults to `nil`, which means
  354. /// the handler is called on `.main`.
  355. /// - encoding: The string encoding. Defaults to `nil`, in which case the encoding will be determined from
  356. /// the server response, falling back to the default HTTP character set, `ISO-8859-1`.
  357. /// - completionHandler: A closure to be executed once the request has finished.
  358. /// - Returns: The request.
  359. @discardableResult
  360. public func responseString(
  361. queue: DispatchQueue? = nil,
  362. encoding: String.Encoding? = nil,
  363. completionHandler: @escaping (DownloadResponse<String>) -> Void)
  364. -> Self
  365. {
  366. return response(
  367. queue: queue,
  368. responseSerializer: StringResponseSerializer(encoding: encoding),
  369. completionHandler: completionHandler
  370. )
  371. }
  372. }
  373. // MARK: - JSON
  374. /// A `ResponseSerializer` that decodes the response data using `JSONSerialization`. By default, a request returning
  375. /// `nil` or no data is considered an error. However, if the response is has a status code valid for empty responses
  376. /// (`204`, `205`), then an `NSNull` value is returned.
  377. public final class JSONResponseSerializer: ResponseSerializer {
  378. /// `JSONSerialization.ReadingOptions` used when serializing a response.
  379. public let options: JSONSerialization.ReadingOptions
  380. /// HTTP response codes for which empty responses are allowed.
  381. public let emptyResponseCodes: Set<Int>
  382. /// HTTP request methods for which empty responses are allowed.
  383. public let emptyRequestMethods: Set<HTTPMethod>
  384. /// Creates an instance with the provided values.
  385. ///
  386. /// - Parameters:
  387. /// - options: The options to use. Defaults to `.allowFragments`.
  388. /// - emptyResponseCodes: The HTTP response codes for which empty responses are allowed. Defaults to
  389. /// `[204, 205]`.
  390. /// - emptyRequestMethods: The HTTP request methods for which empty responses are allowed. Defaults to `[.head]`.
  391. public init(options: JSONSerialization.ReadingOptions = .allowFragments,
  392. emptyResponseCodes: Set<Int> = JSONResponseSerializer.defaultEmptyResponseCodes,
  393. emptyRequestMethods: Set<HTTPMethod> = JSONResponseSerializer.defaultEmptyRequestMethods) {
  394. self.options = options
  395. self.emptyResponseCodes = emptyResponseCodes
  396. self.emptyRequestMethods = emptyRequestMethods
  397. }
  398. public func serialize(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?) throws -> Any {
  399. guard error == nil else { throw error! }
  400. guard let data = data, !data.isEmpty else {
  401. guard emptyResponseAllowed(forRequest: request, response: response) else {
  402. throw AFError.responseSerializationFailed(reason: .inputDataNilOrZeroLength)
  403. }
  404. return NSNull()
  405. }
  406. do {
  407. return try JSONSerialization.jsonObject(with: data, options: options)
  408. } catch {
  409. throw AFError.responseSerializationFailed(reason: .jsonSerializationFailed(error: error))
  410. }
  411. }
  412. }
  413. extension DataRequest {
  414. /// Adds a handler to be called once the request has finished.
  415. ///
  416. /// - Parameters:
  417. /// - queue: The queue on which the completion handler is dispatched. Defaults to `nil`, which means
  418. /// the handler is called on `.main`.
  419. /// - options: The JSON serialization reading options. Defaults to `.allowFragments`.
  420. /// - completionHandler: A closure to be executed once the request has finished.
  421. /// - Returns: The request.
  422. @discardableResult
  423. public func responseJSON(queue: DispatchQueue? = nil,
  424. options: JSONSerialization.ReadingOptions = .allowFragments,
  425. completionHandler: @escaping (DataResponse<Any>) -> Void) -> Self {
  426. return response(queue: queue,
  427. responseSerializer: JSONResponseSerializer(options: options),
  428. completionHandler: completionHandler)
  429. }
  430. }
  431. extension DownloadRequest {
  432. /// Adds a handler to be called once the request has finished.
  433. ///
  434. /// - Parameters:
  435. /// - queue: The queue on which the completion handler is dispatched. Defaults to `nil`, which means
  436. /// the handler is called on `.main`.
  437. /// - options: The JSON serialization reading options. Defaults to `.allowFragments`.
  438. /// - completionHandler: A closure to be executed once the request has finished.
  439. /// - Returns: The request.
  440. @discardableResult
  441. public func responseJSON(
  442. queue: DispatchQueue? = nil,
  443. options: JSONSerialization.ReadingOptions = .allowFragments,
  444. completionHandler: @escaping (DownloadResponse<Any>) -> Void)
  445. -> Self
  446. {
  447. return response(queue: queue,
  448. responseSerializer: JSONResponseSerializer(options: options),
  449. completionHandler: completionHandler)
  450. }
  451. }
  452. // MARK: - Empty
  453. /// A type representing an empty response. Use `Empty.value` to get the instance.
  454. public struct Empty: Decodable {
  455. public static let value = Empty()
  456. }
  457. // MARK: - JSON Decodable
  458. /// A `ResponseSerializer` that decodes the response data as a generic value using a `JSONDecoder`. By default, a
  459. /// request returning `nil` or no data is considered an error. However, if the response is has a status code valid for
  460. /// empty responses (`204`, `205`), then the `Empty.value` value is returned.
  461. public final class JSONDecodableResponseSerializer<T: Decodable>: ResponseSerializer {
  462. /// The `JSONDecoder` instance used to decode responses.
  463. public let decoder: JSONDecoder
  464. /// HTTP response codes for which empty responses are allowed.
  465. public let emptyResponseCodes: Set<Int>
  466. /// HTTP request methods for which empty responses are allowed.
  467. public let emptyRequestMethods: Set<HTTPMethod>
  468. /// Creates an instance using the values provided.
  469. ///
  470. /// - Parameters:
  471. /// - decoder: The `JSONDecoder`. Defaults to a `JSONDecoder()`.
  472. /// - emptyResponseCodes: The HTTP response codes for which empty responses are allowed. Defaults to
  473. /// `[204, 205]`.
  474. /// - emptyRequestMethods: The HTTP request methods for which empty responses are allowed. Defaults to `[.head]`.
  475. public init(decoder: JSONDecoder = JSONDecoder(),
  476. emptyResponseCodes: Set<Int> = JSONDecodableResponseSerializer.defaultEmptyResponseCodes,
  477. emptyRequestMethods: Set<HTTPMethod> = JSONDecodableResponseSerializer.defaultEmptyRequestMethods) {
  478. self.decoder = decoder
  479. self.emptyResponseCodes = emptyResponseCodes
  480. self.emptyRequestMethods = emptyRequestMethods
  481. }
  482. public func serialize(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?) throws -> T {
  483. guard error == nil else { throw error! }
  484. guard let data = data, !data.isEmpty else {
  485. guard emptyResponseAllowed(forRequest: request, response: response) else {
  486. throw AFError.responseSerializationFailed(reason: .inputDataNilOrZeroLength)
  487. }
  488. guard let emptyValue = Empty.value as? T else {
  489. throw AFError.responseSerializationFailed(reason: .invalidEmptyResponse(type: "\(T.self)"))
  490. }
  491. return emptyValue
  492. }
  493. do {
  494. return try decoder.decode(T.self, from: data)
  495. } catch {
  496. throw AFError.responseSerializationFailed(reason: .jsonDecodingFailed(error: error))
  497. }
  498. }
  499. }
  500. extension DataRequest {
  501. /// Adds a handler to be called once the request has finished.
  502. ///
  503. /// - Parameters:
  504. /// - queue: The queue on which the completion handler is dispatched. Defaults to `nil`, which means
  505. /// the handler is called on `.main`.
  506. /// - decoder: The decoder to use to decode the response. Defaults to a `JSONDecoder` with default
  507. /// settings.
  508. /// - completionHandler: A closure to be executed once the request has finished.
  509. /// - Returns: The request.
  510. @discardableResult
  511. public func responseJSONDecodable<T: Decodable>(queue: DispatchQueue? = nil,
  512. decoder: JSONDecoder = JSONDecoder(),
  513. completionHandler: @escaping (DataResponse<T>) -> Void) -> Self {
  514. return response(queue: queue,
  515. responseSerializer: JSONDecodableResponseSerializer(decoder: decoder),
  516. completionHandler: completionHandler)
  517. }
  518. }