ResponseSerialization.swift 66 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270
  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.
  29. associatedtype SerializedObject
  30. /// Serialize the response `Data` into the provided type..
  31. ///
  32. /// - Parameters:
  33. /// - request: `URLRequest` which was used to perform the request, if any.
  34. /// - response: `HTTPURLResponse` received from the server, if any.
  35. /// - data: `Data` returned from the server, if any.
  36. /// - error: `Error` produced by Alamofire or the underlying `URLSession` during the request.
  37. ///
  38. /// - Returns: The `SerializedObject`.
  39. /// - Throws: Any `Error` produced during serialization.
  40. func serialize(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?) throws -> SerializedObject
  41. }
  42. /// The type to which all download response serializers must conform in order to serialize a response.
  43. public protocol DownloadResponseSerializerProtocol {
  44. /// The type of serialized object to be created.
  45. associatedtype SerializedObject
  46. /// Serialize the downloaded response `Data` from disk into the provided type..
  47. ///
  48. /// - Parameters:
  49. /// - request: `URLRequest` which was used to perform the request, if any.
  50. /// - response: `HTTPURLResponse` received from the server, if any.
  51. /// - fileURL: File `URL` to which the response data was downloaded.
  52. /// - error: `Error` produced by Alamofire or the underlying `URLSession` during the request.
  53. ///
  54. /// - Returns: The `SerializedObject`.
  55. /// - Throws: Any `Error` produced during serialization.
  56. func serializeDownload(request: URLRequest?, response: HTTPURLResponse?, fileURL: URL?, error: Error?) throws -> SerializedObject
  57. }
  58. /// A serializer that can handle both data and download responses.
  59. public protocol ResponseSerializer: DataResponseSerializerProtocol & DownloadResponseSerializerProtocol {
  60. /// `DataPreprocessor` used to prepare incoming `Data` for serialization.
  61. var dataPreprocessor: DataPreprocessor { get }
  62. /// `HTTPMethod`s for which empty response bodies are considered appropriate.
  63. var emptyRequestMethods: Set<HTTPMethod> { get }
  64. /// HTTP response codes for which empty response bodies are considered appropriate.
  65. var emptyResponseCodes: Set<Int> { get }
  66. }
  67. /// Type used to preprocess `Data` before it handled by a serializer.
  68. public protocol DataPreprocessor {
  69. /// Process `Data` before it's handled by a serializer.
  70. /// - Parameter data: The raw `Data` to process.
  71. func preprocess(_ data: Data) throws -> Data
  72. }
  73. /// `DataPreprocessor` that returns passed `Data` without any transform.
  74. public struct PassthroughPreprocessor: DataPreprocessor {
  75. public init() {}
  76. public func preprocess(_ data: Data) throws -> Data { data }
  77. }
  78. /// `DataPreprocessor` that trims Google's typical `)]}',\n` XSSI JSON header.
  79. public struct GoogleXSSIPreprocessor: DataPreprocessor {
  80. public init() {}
  81. public func preprocess(_ data: Data) throws -> Data {
  82. (data.prefix(6) == Data(")]}',\n".utf8)) ? data.dropFirst(6) : data
  83. }
  84. }
  85. extension DataPreprocessor where Self == PassthroughPreprocessor {
  86. /// Provides a `PassthroughPreprocessor` instance.
  87. public static var passthrough: PassthroughPreprocessor { PassthroughPreprocessor() }
  88. }
  89. extension DataPreprocessor where Self == GoogleXSSIPreprocessor {
  90. /// Provides a `GoogleXSSIPreprocessor` instance.
  91. public static var googleXSSI: GoogleXSSIPreprocessor { GoogleXSSIPreprocessor() }
  92. }
  93. extension ResponseSerializer {
  94. /// Default `DataPreprocessor`. `PassthroughPreprocessor` by default.
  95. public static var defaultDataPreprocessor: DataPreprocessor { PassthroughPreprocessor() }
  96. /// Default `HTTPMethod`s for which empty response bodies are considered appropriate. `[.head]` by default.
  97. public static var defaultEmptyRequestMethods: Set<HTTPMethod> { [.head] }
  98. /// HTTP response codes for which empty response bodies are considered appropriate. `[204, 205]` by default.
  99. public static var defaultEmptyResponseCodes: Set<Int> { [204, 205] }
  100. public var dataPreprocessor: DataPreprocessor { Self.defaultDataPreprocessor }
  101. public var emptyRequestMethods: Set<HTTPMethod> { Self.defaultEmptyRequestMethods }
  102. public var emptyResponseCodes: Set<Int> { Self.defaultEmptyResponseCodes }
  103. /// Determines whether the `request` allows empty response bodies, if `request` exists.
  104. ///
  105. /// - Parameter request: `URLRequest` to evaluate.
  106. ///
  107. /// - Returns: `Bool` representing the outcome of the evaluation, or `nil` if `request` was `nil`.
  108. public func requestAllowsEmptyResponseData(_ request: URLRequest?) -> Bool? {
  109. request.flatMap(\.httpMethod)
  110. .flatMap(HTTPMethod.init)
  111. .map { emptyRequestMethods.contains($0) }
  112. }
  113. /// Determines whether the `response` allows empty response bodies, if `response` exists`.
  114. ///
  115. /// - Parameter response: `HTTPURLResponse` to evaluate.
  116. ///
  117. /// - Returns: `Bool` representing the outcome of the evaluation, or `nil` if `response` was `nil`.
  118. public func responseAllowsEmptyResponseData(_ response: HTTPURLResponse?) -> Bool? {
  119. response.map(\.statusCode)
  120. .map { emptyResponseCodes.contains($0) }
  121. }
  122. /// Determines whether `request` and `response` allow empty response bodies.
  123. ///
  124. /// - Parameters:
  125. /// - request: `URLRequest` to evaluate.
  126. /// - response: `HTTPURLResponse` to evaluate.
  127. ///
  128. /// - Returns: `true` if `request` or `response` allow empty bodies, `false` otherwise.
  129. public func emptyResponseAllowed(forRequest request: URLRequest?, response: HTTPURLResponse?) -> Bool {
  130. (requestAllowsEmptyResponseData(request) == true) || (responseAllowsEmptyResponseData(response) == true)
  131. }
  132. }
  133. /// By default, any serializer declared to conform to both types will get file serialization for free, as it just feeds
  134. /// the data read from disk into the data response serializer.
  135. extension DownloadResponseSerializerProtocol where Self: DataResponseSerializerProtocol {
  136. public func serializeDownload(request: URLRequest?, response: HTTPURLResponse?, fileURL: URL?, error: Error?) throws -> Self.SerializedObject {
  137. guard error == nil else { throw error! }
  138. guard let fileURL = fileURL else {
  139. throw AFError.responseSerializationFailed(reason: .inputFileNil)
  140. }
  141. let data: Data
  142. do {
  143. data = try Data(contentsOf: fileURL)
  144. } catch {
  145. throw AFError.responseSerializationFailed(reason: .inputFileReadFailed(at: fileURL))
  146. }
  147. do {
  148. return try serialize(request: request, response: response, data: data, error: error)
  149. } catch {
  150. throw error
  151. }
  152. }
  153. }
  154. // MARK: - Default
  155. extension DataRequest {
  156. /// Adds a handler to be called once the request has finished.
  157. ///
  158. /// - Parameters:
  159. /// - queue: The queue on which the completion handler is dispatched. `.main` by default.
  160. /// - completionHandler: The code to be executed once the request has finished.
  161. ///
  162. /// - Returns: The request.
  163. @discardableResult
  164. public func response(queue: DispatchQueue = .main, completionHandler: @escaping (AFDataResponse<Data?>) -> Void) -> Self {
  165. appendResponseSerializer {
  166. // Start work that should be on the serialization queue.
  167. let result = AFResult<Data?>(value: self.data, error: self.error)
  168. // End work that should be on the serialization queue.
  169. self.underlyingQueue.async {
  170. let response = DataResponse(request: self.request,
  171. response: self.response,
  172. data: self.data,
  173. metrics: self.metrics,
  174. serializationDuration: 0,
  175. result: result)
  176. self.eventMonitor?.request(self, didParseResponse: response)
  177. self.responseSerializerDidComplete { queue.async { completionHandler(response) } }
  178. }
  179. }
  180. return self
  181. }
  182. private func _response<Serializer: DataResponseSerializerProtocol>(queue: DispatchQueue = .main,
  183. responseSerializer: Serializer,
  184. completionHandler: @escaping (AFDataResponse<Serializer.SerializedObject>) -> Void)
  185. -> Self {
  186. appendResponseSerializer {
  187. // Start work that should be on the serialization queue.
  188. let start = ProcessInfo.processInfo.systemUptime
  189. let result: AFResult<Serializer.SerializedObject> = Result {
  190. try responseSerializer.serialize(request: self.request,
  191. response: self.response,
  192. data: self.data,
  193. error: self.error)
  194. }.mapError { error in
  195. error.asAFError(or: .responseSerializationFailed(reason: .customSerializationFailed(error: error)))
  196. }
  197. let end = ProcessInfo.processInfo.systemUptime
  198. // End work that should be on the serialization queue.
  199. self.underlyingQueue.async {
  200. let response = DataResponse(request: self.request,
  201. response: self.response,
  202. data: self.data,
  203. metrics: self.metrics,
  204. serializationDuration: end - start,
  205. result: result)
  206. self.eventMonitor?.request(self, didParseResponse: response)
  207. guard !self.isCancelled, let serializerError = result.failure, let delegate = self.delegate else {
  208. self.responseSerializerDidComplete { queue.async { completionHandler(response) } }
  209. return
  210. }
  211. delegate.retryResult(for: self, dueTo: serializerError) { retryResult in
  212. var didComplete: (() -> Void)?
  213. defer {
  214. if let didComplete = didComplete {
  215. self.responseSerializerDidComplete { queue.async { didComplete() } }
  216. }
  217. }
  218. switch retryResult {
  219. case .doNotRetry:
  220. didComplete = { completionHandler(response) }
  221. case let .doNotRetryWithError(retryError):
  222. let result: AFResult<Serializer.SerializedObject> = .failure(retryError.asAFError(orFailWith: "Received retryError was not already AFError"))
  223. let response = DataResponse(request: self.request,
  224. response: self.response,
  225. data: self.data,
  226. metrics: self.metrics,
  227. serializationDuration: end - start,
  228. result: result)
  229. didComplete = { completionHandler(response) }
  230. case .retry, .retryWithDelay:
  231. delegate.retryRequest(self, withDelay: retryResult.delay)
  232. }
  233. }
  234. }
  235. }
  236. return self
  237. }
  238. /// Adds a handler to be called once the request has finished.
  239. ///
  240. /// - Parameters:
  241. /// - queue: The queue on which the completion handler is dispatched. `.main` by default
  242. /// - responseSerializer: The response serializer responsible for serializing the request, response, and data.
  243. /// - completionHandler: The code to be executed once the request has finished.
  244. ///
  245. /// - Returns: The request.
  246. @discardableResult
  247. public func response<Serializer: DataResponseSerializerProtocol>(queue: DispatchQueue = .main,
  248. responseSerializer: Serializer,
  249. completionHandler: @escaping (AFDataResponse<Serializer.SerializedObject>) -> Void)
  250. -> Self {
  251. _response(queue: queue, responseSerializer: responseSerializer, completionHandler: completionHandler)
  252. }
  253. /// Adds a handler to be called once the request has finished.
  254. ///
  255. /// - Parameters:
  256. /// - queue: The queue on which the completion handler is dispatched. `.main` by default
  257. /// - responseSerializer: The response serializer responsible for serializing the request, response, and data.
  258. /// - completionHandler: The code to be executed once the request has finished.
  259. ///
  260. /// - Returns: The request.
  261. @discardableResult
  262. public func response<Serializer: ResponseSerializer>(queue: DispatchQueue = .main,
  263. responseSerializer: Serializer,
  264. completionHandler: @escaping (AFDataResponse<Serializer.SerializedObject>) -> Void)
  265. -> Self {
  266. _response(queue: queue, responseSerializer: responseSerializer, completionHandler: completionHandler)
  267. }
  268. }
  269. extension DownloadRequest {
  270. /// Adds a handler to be called once the request has finished.
  271. ///
  272. /// - Parameters:
  273. /// - queue: The queue on which the completion handler is dispatched. `.main` by default.
  274. /// - completionHandler: The code to be executed once the request has finished.
  275. ///
  276. /// - Returns: The request.
  277. @discardableResult
  278. public func response(queue: DispatchQueue = .main,
  279. completionHandler: @escaping (AFDownloadResponse<URL?>) -> Void)
  280. -> Self {
  281. appendResponseSerializer {
  282. // Start work that should be on the serialization queue.
  283. let result = AFResult<URL?>(value: self.fileURL, error: self.error)
  284. // End work that should be on the serialization queue.
  285. self.underlyingQueue.async {
  286. let response = DownloadResponse(request: self.request,
  287. response: self.response,
  288. fileURL: self.fileURL,
  289. resumeData: self.resumeData,
  290. metrics: self.metrics,
  291. serializationDuration: 0,
  292. result: result)
  293. self.eventMonitor?.request(self, didParseResponse: response)
  294. self.responseSerializerDidComplete { queue.async { completionHandler(response) } }
  295. }
  296. }
  297. return self
  298. }
  299. private func _response<Serializer: DownloadResponseSerializerProtocol>(queue: DispatchQueue = .main,
  300. responseSerializer: Serializer,
  301. completionHandler: @escaping (AFDownloadResponse<Serializer.SerializedObject>) -> Void)
  302. -> Self {
  303. appendResponseSerializer {
  304. // Start work that should be on the serialization queue.
  305. let start = ProcessInfo.processInfo.systemUptime
  306. let result: AFResult<Serializer.SerializedObject> = Result {
  307. try responseSerializer.serializeDownload(request: self.request,
  308. response: self.response,
  309. fileURL: self.fileURL,
  310. error: self.error)
  311. }.mapError { error in
  312. error.asAFError(or: .responseSerializationFailed(reason: .customSerializationFailed(error: error)))
  313. }
  314. let end = ProcessInfo.processInfo.systemUptime
  315. // End work that should be on the serialization queue.
  316. self.underlyingQueue.async {
  317. let response = DownloadResponse(request: self.request,
  318. response: self.response,
  319. fileURL: self.fileURL,
  320. resumeData: self.resumeData,
  321. metrics: self.metrics,
  322. serializationDuration: end - start,
  323. result: result)
  324. self.eventMonitor?.request(self, didParseResponse: response)
  325. guard let serializerError = result.failure, let delegate = self.delegate else {
  326. self.responseSerializerDidComplete { queue.async { completionHandler(response) } }
  327. return
  328. }
  329. delegate.retryResult(for: self, dueTo: serializerError) { retryResult in
  330. var didComplete: (() -> Void)?
  331. defer {
  332. if let didComplete = didComplete {
  333. self.responseSerializerDidComplete { queue.async { didComplete() } }
  334. }
  335. }
  336. switch retryResult {
  337. case .doNotRetry:
  338. didComplete = { completionHandler(response) }
  339. case let .doNotRetryWithError(retryError):
  340. let result: AFResult<Serializer.SerializedObject> = .failure(retryError.asAFError(orFailWith: "Received retryError was not already AFError"))
  341. let response = DownloadResponse(request: self.request,
  342. response: self.response,
  343. fileURL: self.fileURL,
  344. resumeData: self.resumeData,
  345. metrics: self.metrics,
  346. serializationDuration: end - start,
  347. result: result)
  348. didComplete = { completionHandler(response) }
  349. case .retry, .retryWithDelay:
  350. delegate.retryRequest(self, withDelay: retryResult.delay)
  351. }
  352. }
  353. }
  354. }
  355. return self
  356. }
  357. /// Adds a handler to be called once the request has finished.
  358. ///
  359. /// - Parameters:
  360. /// - queue: The queue on which the completion handler is dispatched. `.main` by default.
  361. /// - responseSerializer: The response serializer responsible for serializing the request, response, and data
  362. /// contained in the destination `URL`.
  363. /// - completionHandler: The code to be executed once the request has finished.
  364. ///
  365. /// - Returns: The request.
  366. @discardableResult
  367. public func response<Serializer: DownloadResponseSerializerProtocol>(queue: DispatchQueue = .main,
  368. responseSerializer: Serializer,
  369. completionHandler: @escaping (AFDownloadResponse<Serializer.SerializedObject>) -> Void)
  370. -> Self {
  371. _response(queue: queue, responseSerializer: responseSerializer, completionHandler: completionHandler)
  372. }
  373. /// Adds a handler to be called once the request has finished.
  374. ///
  375. /// - Parameters:
  376. /// - queue: The queue on which the completion handler is dispatched. `.main` by default.
  377. /// - responseSerializer: The response serializer responsible for serializing the request, response, and data
  378. /// contained in the destination `URL`.
  379. /// - completionHandler: The code to be executed once the request has finished.
  380. ///
  381. /// - Returns: The request.
  382. @discardableResult
  383. public func response<Serializer: ResponseSerializer>(queue: DispatchQueue = .main,
  384. responseSerializer: Serializer,
  385. completionHandler: @escaping (AFDownloadResponse<Serializer.SerializedObject>) -> Void)
  386. -> Self {
  387. _response(queue: queue, responseSerializer: responseSerializer, completionHandler: completionHandler)
  388. }
  389. }
  390. // MARK: - URL
  391. /// A `DownloadResponseSerializerProtocol` that performs only `Error` checking and ensures that a downloaded `fileURL`
  392. /// is present.
  393. public struct URLResponseSerializer: DownloadResponseSerializerProtocol {
  394. /// Creates an instance.
  395. public init() {}
  396. public func serializeDownload(request: URLRequest?,
  397. response: HTTPURLResponse?,
  398. fileURL: URL?,
  399. error: Error?) throws -> URL {
  400. guard error == nil else { throw error! }
  401. guard let url = fileURL else {
  402. throw AFError.responseSerializationFailed(reason: .inputFileNil)
  403. }
  404. return url
  405. }
  406. }
  407. extension DownloadResponseSerializerProtocol where Self == URLResponseSerializer {
  408. /// Provides a `URLResponseSerializer` instance.
  409. public static var url: URLResponseSerializer { URLResponseSerializer() }
  410. }
  411. extension DownloadRequest {
  412. /// Adds a handler using a `URLResponseSerializer` to be called once the request is finished.
  413. ///
  414. /// - Parameters:
  415. /// - queue: The queue on which the completion handler is called. `.main` by default.
  416. /// - completionHandler: A closure to be executed once the request has finished.
  417. ///
  418. /// - Returns: The request.
  419. @discardableResult
  420. public func responseURL(queue: DispatchQueue = .main,
  421. completionHandler: @escaping (AFDownloadResponse<URL>) -> Void) -> Self {
  422. response(queue: queue, responseSerializer: URLResponseSerializer(), completionHandler: completionHandler)
  423. }
  424. }
  425. // MARK: - Data
  426. /// A `ResponseSerializer` that performs minimal response checking and returns any response `Data` as-is. By default, a
  427. /// request returning `nil` or no data is considered an error. However, if the request has an `HTTPMethod` or the
  428. /// response has an HTTP status code valid for empty responses, then an empty `Data` value is returned.
  429. public final class DataResponseSerializer: ResponseSerializer {
  430. public let dataPreprocessor: DataPreprocessor
  431. public let emptyResponseCodes: Set<Int>
  432. public let emptyRequestMethods: Set<HTTPMethod>
  433. /// Creates a `DataResponseSerializer` using the provided parameters.
  434. ///
  435. /// - Parameters:
  436. /// - dataPreprocessor: `DataPreprocessor` used to prepare the received `Data` for serialization.
  437. /// - emptyResponseCodes: The HTTP response codes for which empty responses are allowed. `[204, 205]` by default.
  438. /// - emptyRequestMethods: The HTTP request methods for which empty responses are allowed. `[.head]` by default.
  439. public init(dataPreprocessor: DataPreprocessor = DataResponseSerializer.defaultDataPreprocessor,
  440. emptyResponseCodes: Set<Int> = DataResponseSerializer.defaultEmptyResponseCodes,
  441. emptyRequestMethods: Set<HTTPMethod> = DataResponseSerializer.defaultEmptyRequestMethods) {
  442. self.dataPreprocessor = dataPreprocessor
  443. self.emptyResponseCodes = emptyResponseCodes
  444. self.emptyRequestMethods = emptyRequestMethods
  445. }
  446. public func serialize(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?) throws -> Data {
  447. guard error == nil else { throw error! }
  448. guard var data = data, !data.isEmpty else {
  449. guard emptyResponseAllowed(forRequest: request, response: response) else {
  450. throw AFError.responseSerializationFailed(reason: .inputDataNilOrZeroLength)
  451. }
  452. return Data()
  453. }
  454. data = try dataPreprocessor.preprocess(data)
  455. return data
  456. }
  457. }
  458. extension ResponseSerializer where Self == DataResponseSerializer {
  459. /// Provides a default `DataResponseSerializer` instance.
  460. public static var data: DataResponseSerializer { DataResponseSerializer() }
  461. /// Creates a `DataResponseSerializer` using the provided parameters.
  462. ///
  463. /// - Parameters:
  464. /// - dataPreprocessor: `DataPreprocessor` used to prepare the received `Data` for serialization.
  465. /// - emptyResponseCodes: The HTTP response codes for which empty responses are allowed. `[204, 205]` by default.
  466. /// - emptyRequestMethods: The HTTP request methods for which empty responses are allowed. `[.head]` by default.
  467. ///
  468. /// - Returns: The `DataResponseSerializer`.
  469. public static func data(dataPreprocessor: DataPreprocessor = DataResponseSerializer.defaultDataPreprocessor,
  470. emptyResponseCodes: Set<Int> = DataResponseSerializer.defaultEmptyResponseCodes,
  471. emptyRequestMethods: Set<HTTPMethod> = DataResponseSerializer.defaultEmptyRequestMethods) -> DataResponseSerializer {
  472. DataResponseSerializer(dataPreprocessor: dataPreprocessor,
  473. emptyResponseCodes: emptyResponseCodes,
  474. emptyRequestMethods: emptyRequestMethods)
  475. }
  476. }
  477. extension DataRequest {
  478. /// Adds a handler using a `DataResponseSerializer` to be called once the request has finished.
  479. ///
  480. /// - Parameters:
  481. /// - queue: The queue on which the completion handler is called. `.main` by default.
  482. /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the
  483. /// `completionHandler`. `PassthroughPreprocessor()` by default.
  484. /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default.
  485. /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default.
  486. /// - completionHandler: A closure to be executed once the request has finished.
  487. ///
  488. /// - Returns: The request.
  489. @discardableResult
  490. public func responseData(queue: DispatchQueue = .main,
  491. dataPreprocessor: DataPreprocessor = DataResponseSerializer.defaultDataPreprocessor,
  492. emptyResponseCodes: Set<Int> = DataResponseSerializer.defaultEmptyResponseCodes,
  493. emptyRequestMethods: Set<HTTPMethod> = DataResponseSerializer.defaultEmptyRequestMethods,
  494. completionHandler: @escaping (AFDataResponse<Data>) -> Void) -> Self {
  495. response(queue: queue,
  496. responseSerializer: DataResponseSerializer(dataPreprocessor: dataPreprocessor,
  497. emptyResponseCodes: emptyResponseCodes,
  498. emptyRequestMethods: emptyRequestMethods),
  499. completionHandler: completionHandler)
  500. }
  501. }
  502. extension DownloadRequest {
  503. /// Adds a handler using a `DataResponseSerializer` to be called once the request has finished.
  504. ///
  505. /// - Parameters:
  506. /// - queue: The queue on which the completion handler is called. `.main` by default.
  507. /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the
  508. /// `completionHandler`. `PassthroughPreprocessor()` by default.
  509. /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default.
  510. /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default.
  511. /// - completionHandler: A closure to be executed once the request has finished.
  512. ///
  513. /// - Returns: The request.
  514. @discardableResult
  515. public func responseData(queue: DispatchQueue = .main,
  516. dataPreprocessor: DataPreprocessor = DataResponseSerializer.defaultDataPreprocessor,
  517. emptyResponseCodes: Set<Int> = DataResponseSerializer.defaultEmptyResponseCodes,
  518. emptyRequestMethods: Set<HTTPMethod> = DataResponseSerializer.defaultEmptyRequestMethods,
  519. completionHandler: @escaping (AFDownloadResponse<Data>) -> Void) -> Self {
  520. response(queue: queue,
  521. responseSerializer: DataResponseSerializer(dataPreprocessor: dataPreprocessor,
  522. emptyResponseCodes: emptyResponseCodes,
  523. emptyRequestMethods: emptyRequestMethods),
  524. completionHandler: completionHandler)
  525. }
  526. }
  527. // MARK: - String
  528. /// A `ResponseSerializer` that decodes the response data as a `String`. By default, a request returning `nil` or no
  529. /// data is considered an error. However, if the request has an `HTTPMethod` or the response has an HTTP status code
  530. /// valid for empty responses, then an empty `String` is returned.
  531. public final class StringResponseSerializer: ResponseSerializer {
  532. public let dataPreprocessor: DataPreprocessor
  533. /// Optional string encoding used to validate the response.
  534. public let encoding: String.Encoding?
  535. public let emptyResponseCodes: Set<Int>
  536. public let emptyRequestMethods: Set<HTTPMethod>
  537. /// Creates an instance with the provided values.
  538. ///
  539. /// - Parameters:
  540. /// - dataPreprocessor: `DataPreprocessor` used to prepare the received `Data` for serialization.
  541. /// - encoding: A string encoding. Defaults to `nil`, in which case the encoding will be determined
  542. /// from the server response, falling back to the default HTTP character set, `ISO-8859-1`.
  543. /// - emptyResponseCodes: The HTTP response codes for which empty responses are allowed. `[204, 205]` by default.
  544. /// - emptyRequestMethods: The HTTP request methods for which empty responses are allowed. `[.head]` by default.
  545. public init(dataPreprocessor: DataPreprocessor = StringResponseSerializer.defaultDataPreprocessor,
  546. encoding: String.Encoding? = nil,
  547. emptyResponseCodes: Set<Int> = StringResponseSerializer.defaultEmptyResponseCodes,
  548. emptyRequestMethods: Set<HTTPMethod> = StringResponseSerializer.defaultEmptyRequestMethods) {
  549. self.dataPreprocessor = dataPreprocessor
  550. self.encoding = encoding
  551. self.emptyResponseCodes = emptyResponseCodes
  552. self.emptyRequestMethods = emptyRequestMethods
  553. }
  554. public func serialize(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?) throws -> String {
  555. guard error == nil else { throw error! }
  556. guard var data = data, !data.isEmpty else {
  557. guard emptyResponseAllowed(forRequest: request, response: response) else {
  558. throw AFError.responseSerializationFailed(reason: .inputDataNilOrZeroLength)
  559. }
  560. return ""
  561. }
  562. data = try dataPreprocessor.preprocess(data)
  563. var convertedEncoding = encoding
  564. if let encodingName = response?.textEncodingName, convertedEncoding == nil {
  565. convertedEncoding = String.Encoding(ianaCharsetName: encodingName)
  566. }
  567. let actualEncoding = convertedEncoding ?? .isoLatin1
  568. guard let string = String(data: data, encoding: actualEncoding) else {
  569. throw AFError.responseSerializationFailed(reason: .stringSerializationFailed(encoding: actualEncoding))
  570. }
  571. return string
  572. }
  573. }
  574. extension ResponseSerializer where Self == StringResponseSerializer {
  575. /// Provides a default `StringResponseSerializer` instance.
  576. public static var string: StringResponseSerializer { StringResponseSerializer() }
  577. /// Creates a `StringResponseSerializer` with the provided values.
  578. ///
  579. /// - Parameters:
  580. /// - dataPreprocessor: `DataPreprocessor` used to prepare the received `Data` for serialization.
  581. /// - encoding: A string encoding. Defaults to `nil`, in which case the encoding will be determined
  582. /// from the server response, falling back to the default HTTP character set, `ISO-8859-1`.
  583. /// - emptyResponseCodes: The HTTP response codes for which empty responses are allowed. `[204, 205]` by default.
  584. /// - emptyRequestMethods: The HTTP request methods for which empty responses are allowed. `[.head]` by default.
  585. ///
  586. /// - Returns: The `StringResponseSerializer`.
  587. public static func string(dataPreprocessor: DataPreprocessor = StringResponseSerializer.defaultDataPreprocessor,
  588. encoding: String.Encoding? = nil,
  589. emptyResponseCodes: Set<Int> = StringResponseSerializer.defaultEmptyResponseCodes,
  590. emptyRequestMethods: Set<HTTPMethod> = StringResponseSerializer.defaultEmptyRequestMethods) -> StringResponseSerializer {
  591. StringResponseSerializer(dataPreprocessor: dataPreprocessor,
  592. encoding: encoding,
  593. emptyResponseCodes: emptyResponseCodes,
  594. emptyRequestMethods: emptyRequestMethods)
  595. }
  596. }
  597. extension DataRequest {
  598. /// Adds a handler using a `StringResponseSerializer` to be called once the request has finished.
  599. ///
  600. /// - Parameters:
  601. /// - queue: The queue on which the completion handler is dispatched. `.main` by default.
  602. /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the
  603. /// `completionHandler`. `PassthroughPreprocessor()` by default.
  604. /// - encoding: The string encoding. Defaults to `nil`, in which case the encoding will be determined
  605. /// from the server response, falling back to the default HTTP character set, `ISO-8859-1`.
  606. /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default.
  607. /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default.
  608. /// - completionHandler: A closure to be executed once the request has finished.
  609. ///
  610. /// - Returns: The request.
  611. @discardableResult
  612. public func responseString(queue: DispatchQueue = .main,
  613. dataPreprocessor: DataPreprocessor = StringResponseSerializer.defaultDataPreprocessor,
  614. encoding: String.Encoding? = nil,
  615. emptyResponseCodes: Set<Int> = StringResponseSerializer.defaultEmptyResponseCodes,
  616. emptyRequestMethods: Set<HTTPMethod> = StringResponseSerializer.defaultEmptyRequestMethods,
  617. completionHandler: @escaping (AFDataResponse<String>) -> Void) -> Self {
  618. response(queue: queue,
  619. responseSerializer: StringResponseSerializer(dataPreprocessor: dataPreprocessor,
  620. encoding: encoding,
  621. emptyResponseCodes: emptyResponseCodes,
  622. emptyRequestMethods: emptyRequestMethods),
  623. completionHandler: completionHandler)
  624. }
  625. }
  626. extension DownloadRequest {
  627. /// Adds a handler using a `StringResponseSerializer` to be called once the request has finished.
  628. ///
  629. /// - Parameters:
  630. /// - queue: The queue on which the completion handler is dispatched. `.main` by default.
  631. /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the
  632. /// `completionHandler`. `PassthroughPreprocessor()` by default.
  633. /// - encoding: The string encoding. Defaults to `nil`, in which case the encoding will be determined
  634. /// from the server response, falling back to the default HTTP character set, `ISO-8859-1`.
  635. /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default.
  636. /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default.
  637. /// - completionHandler: A closure to be executed once the request has finished.
  638. ///
  639. /// - Returns: The request.
  640. @discardableResult
  641. public func responseString(queue: DispatchQueue = .main,
  642. dataPreprocessor: DataPreprocessor = StringResponseSerializer.defaultDataPreprocessor,
  643. encoding: String.Encoding? = nil,
  644. emptyResponseCodes: Set<Int> = StringResponseSerializer.defaultEmptyResponseCodes,
  645. emptyRequestMethods: Set<HTTPMethod> = StringResponseSerializer.defaultEmptyRequestMethods,
  646. completionHandler: @escaping (AFDownloadResponse<String>) -> Void) -> Self {
  647. response(queue: queue,
  648. responseSerializer: StringResponseSerializer(dataPreprocessor: dataPreprocessor,
  649. encoding: encoding,
  650. emptyResponseCodes: emptyResponseCodes,
  651. emptyRequestMethods: emptyRequestMethods),
  652. completionHandler: completionHandler)
  653. }
  654. }
  655. // MARK: - JSON
  656. /// A `ResponseSerializer` that decodes the response data using `JSONSerialization`. By default, a request returning
  657. /// `nil` or no data is considered an error. However, if the request has an `HTTPMethod` or the response has an
  658. /// HTTP status code valid for empty responses, then an `NSNull` value is returned.
  659. @available(*, deprecated, message: "JSONResponseSerializer deprecated and will be removed in Alamofire 6. Use DecodableResponseSerializer instead.")
  660. public final class JSONResponseSerializer: ResponseSerializer {
  661. public let dataPreprocessor: DataPreprocessor
  662. public let emptyResponseCodes: Set<Int>
  663. public let emptyRequestMethods: Set<HTTPMethod>
  664. /// `JSONSerialization.ReadingOptions` used when serializing a response.
  665. public let options: JSONSerialization.ReadingOptions
  666. /// Creates an instance with the provided values.
  667. ///
  668. /// - Parameters:
  669. /// - dataPreprocessor: `DataPreprocessor` used to prepare the received `Data` for serialization.
  670. /// - emptyResponseCodes: The HTTP response codes for which empty responses are allowed. `[204, 205]` by default.
  671. /// - emptyRequestMethods: The HTTP request methods for which empty responses are allowed. `[.head]` by default.
  672. /// - options: The options to use. `.allowFragments` by default.
  673. public init(dataPreprocessor: DataPreprocessor = JSONResponseSerializer.defaultDataPreprocessor,
  674. emptyResponseCodes: Set<Int> = JSONResponseSerializer.defaultEmptyResponseCodes,
  675. emptyRequestMethods: Set<HTTPMethod> = JSONResponseSerializer.defaultEmptyRequestMethods,
  676. options: JSONSerialization.ReadingOptions = .allowFragments) {
  677. self.dataPreprocessor = dataPreprocessor
  678. self.emptyResponseCodes = emptyResponseCodes
  679. self.emptyRequestMethods = emptyRequestMethods
  680. self.options = options
  681. }
  682. public func serialize(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?) throws -> Any {
  683. guard error == nil else { throw error! }
  684. guard var data = data, !data.isEmpty else {
  685. guard emptyResponseAllowed(forRequest: request, response: response) else {
  686. throw AFError.responseSerializationFailed(reason: .inputDataNilOrZeroLength)
  687. }
  688. return NSNull()
  689. }
  690. data = try dataPreprocessor.preprocess(data)
  691. do {
  692. return try JSONSerialization.jsonObject(with: data, options: options)
  693. } catch {
  694. throw AFError.responseSerializationFailed(reason: .jsonSerializationFailed(error: error))
  695. }
  696. }
  697. }
  698. extension DataRequest {
  699. /// Adds a handler using a `JSONResponseSerializer` to be called once the request has finished.
  700. ///
  701. /// - Parameters:
  702. /// - queue: The queue on which the completion handler is dispatched. `.main` by default.
  703. /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the
  704. /// `completionHandler`. `PassthroughPreprocessor()` by default.
  705. /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default.
  706. /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default.
  707. /// - options: `JSONSerialization.ReadingOptions` used when parsing the response. `.allowFragments`
  708. /// by default.
  709. /// - completionHandler: A closure to be executed once the request has finished.
  710. ///
  711. /// - Returns: The request.
  712. @available(*, deprecated, message: "responseJSON deprecated and will be removed in Alamofire 6. Use responseDecodable instead.")
  713. @discardableResult
  714. public func responseJSON(queue: DispatchQueue = .main,
  715. dataPreprocessor: DataPreprocessor = JSONResponseSerializer.defaultDataPreprocessor,
  716. emptyResponseCodes: Set<Int> = JSONResponseSerializer.defaultEmptyResponseCodes,
  717. emptyRequestMethods: Set<HTTPMethod> = JSONResponseSerializer.defaultEmptyRequestMethods,
  718. options: JSONSerialization.ReadingOptions = .allowFragments,
  719. completionHandler: @escaping (AFDataResponse<Any>) -> Void) -> Self {
  720. response(queue: queue,
  721. responseSerializer: JSONResponseSerializer(dataPreprocessor: dataPreprocessor,
  722. emptyResponseCodes: emptyResponseCodes,
  723. emptyRequestMethods: emptyRequestMethods,
  724. options: options),
  725. completionHandler: completionHandler)
  726. }
  727. }
  728. extension DownloadRequest {
  729. /// Adds a handler using a `JSONResponseSerializer` to be called once the request has finished.
  730. ///
  731. /// - Parameters:
  732. /// - queue: The queue on which the completion handler is dispatched. `.main` by default.
  733. /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the
  734. /// `completionHandler`. `PassthroughPreprocessor()` by default.
  735. /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default.
  736. /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default.
  737. /// - options: `JSONSerialization.ReadingOptions` used when parsing the response. `.allowFragments`
  738. /// by default.
  739. /// - completionHandler: A closure to be executed once the request has finished.
  740. ///
  741. /// - Returns: The request.
  742. @available(*, deprecated, message: "responseJSON deprecated and will be removed in Alamofire 6. Use responseDecodable instead.")
  743. @discardableResult
  744. public func responseJSON(queue: DispatchQueue = .main,
  745. dataPreprocessor: DataPreprocessor = JSONResponseSerializer.defaultDataPreprocessor,
  746. emptyResponseCodes: Set<Int> = JSONResponseSerializer.defaultEmptyResponseCodes,
  747. emptyRequestMethods: Set<HTTPMethod> = JSONResponseSerializer.defaultEmptyRequestMethods,
  748. options: JSONSerialization.ReadingOptions = .allowFragments,
  749. completionHandler: @escaping (AFDownloadResponse<Any>) -> Void) -> Self {
  750. response(queue: queue,
  751. responseSerializer: JSONResponseSerializer(dataPreprocessor: dataPreprocessor,
  752. emptyResponseCodes: emptyResponseCodes,
  753. emptyRequestMethods: emptyRequestMethods,
  754. options: options),
  755. completionHandler: completionHandler)
  756. }
  757. }
  758. // MARK: - Empty
  759. /// Protocol representing an empty response. Use `T.emptyValue()` to get an instance.
  760. public protocol EmptyResponse {
  761. /// Empty value for the conforming type.
  762. ///
  763. /// - Returns: Value of `Self` to use for empty values.
  764. static func emptyValue() -> Self
  765. }
  766. /// Type representing an empty value. Use `Empty.value` to get the static instance.
  767. public struct Empty: Codable {
  768. /// Static `Empty` instance used for all `Empty` responses.
  769. public static let value = Empty()
  770. }
  771. extension Empty: EmptyResponse {
  772. public static func emptyValue() -> Empty {
  773. value
  774. }
  775. }
  776. // MARK: - DataDecoder Protocol
  777. /// Any type which can decode `Data` into a `Decodable` type.
  778. public protocol DataDecoder {
  779. /// Decode `Data` into the provided type.
  780. ///
  781. /// - Parameters:
  782. /// - type: The `Type` to be decoded.
  783. /// - data: The `Data` to be decoded.
  784. ///
  785. /// - Returns: The decoded value of type `D`.
  786. /// - Throws: Any error that occurs during decode.
  787. func decode<D: Decodable>(_ type: D.Type, from data: Data) throws -> D
  788. }
  789. /// `JSONDecoder` automatically conforms to `DataDecoder`.
  790. extension JSONDecoder: DataDecoder {}
  791. /// `PropertyListDecoder` automatically conforms to `DataDecoder`.
  792. extension PropertyListDecoder: DataDecoder {}
  793. // MARK: - Decodable
  794. /// A `ResponseSerializer` that decodes the response data as a generic value using any type that conforms to
  795. /// `DataDecoder`. By default, this is an instance of `JSONDecoder`. Additionally, a request returning `nil` or no data
  796. /// is considered an error. However, if the request has an `HTTPMethod` or the response has an HTTP status code valid
  797. /// for empty responses then an empty value will be returned. If the decoded type conforms to `EmptyResponse`, the
  798. /// type's `emptyValue()` will be returned. If the decoded type is `Empty`, the `.value` instance is returned. If the
  799. /// decoded type *does not* conform to `EmptyResponse` and isn't `Empty`, an error will be produced.
  800. public final class DecodableResponseSerializer<T: Decodable>: ResponseSerializer {
  801. public let dataPreprocessor: DataPreprocessor
  802. /// The `DataDecoder` instance used to decode responses.
  803. public let decoder: DataDecoder
  804. public let emptyResponseCodes: Set<Int>
  805. public let emptyRequestMethods: Set<HTTPMethod>
  806. /// Creates an instance using the values provided.
  807. ///
  808. /// - Parameters:
  809. /// - dataPreprocessor: `DataPreprocessor` used to prepare the received `Data` for serialization.
  810. /// - decoder: The `DataDecoder`. `JSONDecoder()` by default.
  811. /// - emptyResponseCodes: The HTTP response codes for which empty responses are allowed. `[204, 205]` by default.
  812. /// - emptyRequestMethods: The HTTP request methods for which empty responses are allowed. `[.head]` by default.
  813. public init(dataPreprocessor: DataPreprocessor = DecodableResponseSerializer.defaultDataPreprocessor,
  814. decoder: DataDecoder = JSONDecoder(),
  815. emptyResponseCodes: Set<Int> = DecodableResponseSerializer.defaultEmptyResponseCodes,
  816. emptyRequestMethods: Set<HTTPMethod> = DecodableResponseSerializer.defaultEmptyRequestMethods) {
  817. self.dataPreprocessor = dataPreprocessor
  818. self.decoder = decoder
  819. self.emptyResponseCodes = emptyResponseCodes
  820. self.emptyRequestMethods = emptyRequestMethods
  821. }
  822. public func serialize(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?) throws -> T {
  823. guard error == nil else { throw error! }
  824. guard var data = data, !data.isEmpty else {
  825. guard emptyResponseAllowed(forRequest: request, response: response) else {
  826. throw AFError.responseSerializationFailed(reason: .inputDataNilOrZeroLength)
  827. }
  828. guard let emptyResponseType = T.self as? EmptyResponse.Type, let emptyValue = emptyResponseType.emptyValue() as? T else {
  829. throw AFError.responseSerializationFailed(reason: .invalidEmptyResponse(type: "\(T.self)"))
  830. }
  831. return emptyValue
  832. }
  833. data = try dataPreprocessor.preprocess(data)
  834. do {
  835. return try decoder.decode(T.self, from: data)
  836. } catch {
  837. throw AFError.responseSerializationFailed(reason: .decodingFailed(error: error))
  838. }
  839. }
  840. }
  841. extension ResponseSerializer {
  842. /// Creates a `DecodableResponseSerializer` using the values provided.
  843. ///
  844. /// - Parameters:
  845. /// - type: `Decodable` type to decode from response data.
  846. /// - dataPreprocessor: `DataPreprocessor` used to prepare the received `Data` for serialization.
  847. /// - decoder: The `DataDecoder`. `JSONDecoder()` by default.
  848. /// - emptyResponseCodes: The HTTP response codes for which empty responses are allowed. `[204, 205]` by default.
  849. /// - emptyRequestMethods: The HTTP request methods for which empty responses are allowed. `[.head]` by default.
  850. ///
  851. /// - Returns: The `DecodableResponseSerializer`.
  852. public static func decodable<T: Decodable>(of type: T.Type,
  853. dataPreprocessor: DataPreprocessor = DecodableResponseSerializer<T>.defaultDataPreprocessor,
  854. decoder: DataDecoder = JSONDecoder(),
  855. emptyResponseCodes: Set<Int> = DecodableResponseSerializer<T>.defaultEmptyResponseCodes,
  856. emptyRequestMethods: Set<HTTPMethod> = DecodableResponseSerializer<T>.defaultEmptyRequestMethods) -> DecodableResponseSerializer<T> where Self == DecodableResponseSerializer<T> {
  857. DecodableResponseSerializer<T>(dataPreprocessor: dataPreprocessor,
  858. decoder: decoder,
  859. emptyResponseCodes: emptyResponseCodes,
  860. emptyRequestMethods: emptyRequestMethods)
  861. }
  862. }
  863. extension DataRequest {
  864. /// Adds a handler using a `DecodableResponseSerializer` to be called once the request has finished.
  865. ///
  866. /// - Parameters:
  867. /// - type: `Decodable` type to decode from response data.
  868. /// - queue: The queue on which the completion handler is dispatched. `.main` by default.
  869. /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the
  870. /// `completionHandler`. `PassthroughPreprocessor()` by default.
  871. /// - decoder: `DataDecoder` to use to decode the response. `JSONDecoder()` by default.
  872. /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default.
  873. /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default.
  874. /// - completionHandler: A closure to be executed once the request has finished.
  875. ///
  876. /// - Returns: The request.
  877. @discardableResult
  878. public func responseDecodable<T: Decodable>(of type: T.Type = T.self,
  879. queue: DispatchQueue = .main,
  880. dataPreprocessor: DataPreprocessor = DecodableResponseSerializer<T>.defaultDataPreprocessor,
  881. decoder: DataDecoder = JSONDecoder(),
  882. emptyResponseCodes: Set<Int> = DecodableResponseSerializer<T>.defaultEmptyResponseCodes,
  883. emptyRequestMethods: Set<HTTPMethod> = DecodableResponseSerializer<T>.defaultEmptyRequestMethods,
  884. completionHandler: @escaping (AFDataResponse<T>) -> Void) -> Self {
  885. response(queue: queue,
  886. responseSerializer: DecodableResponseSerializer(dataPreprocessor: dataPreprocessor,
  887. decoder: decoder,
  888. emptyResponseCodes: emptyResponseCodes,
  889. emptyRequestMethods: emptyRequestMethods),
  890. completionHandler: completionHandler)
  891. }
  892. }
  893. extension DownloadRequest {
  894. /// Adds a handler using a `DecodableResponseSerializer` to be called once the request has finished.
  895. ///
  896. /// - Parameters:
  897. /// - type: `Decodable` type to decode from response data.
  898. /// - queue: The queue on which the completion handler is dispatched. `.main` by default.
  899. /// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the
  900. /// `completionHandler`. `PassthroughPreprocessor()` by default.
  901. /// - decoder: `DataDecoder` to use to decode the response. `JSONDecoder()` by default.
  902. /// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default.
  903. /// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default.
  904. /// - completionHandler: A closure to be executed once the request has finished.
  905. ///
  906. /// - Returns: The request.
  907. @discardableResult
  908. public func responseDecodable<T: Decodable>(of type: T.Type = T.self,
  909. queue: DispatchQueue = .main,
  910. dataPreprocessor: DataPreprocessor = DecodableResponseSerializer<T>.defaultDataPreprocessor,
  911. decoder: DataDecoder = JSONDecoder(),
  912. emptyResponseCodes: Set<Int> = DecodableResponseSerializer<T>.defaultEmptyResponseCodes,
  913. emptyRequestMethods: Set<HTTPMethod> = DecodableResponseSerializer<T>.defaultEmptyRequestMethods,
  914. completionHandler: @escaping (AFDownloadResponse<T>) -> Void) -> Self {
  915. response(queue: queue,
  916. responseSerializer: DecodableResponseSerializer(dataPreprocessor: dataPreprocessor,
  917. decoder: decoder,
  918. emptyResponseCodes: emptyResponseCodes,
  919. emptyRequestMethods: emptyRequestMethods),
  920. completionHandler: completionHandler)
  921. }
  922. }
  923. // MARK: - DataStreamRequest
  924. /// A type which can serialize incoming `Data`.
  925. public protocol DataStreamSerializer {
  926. /// Type produced from the serialized `Data`.
  927. associatedtype SerializedObject
  928. /// Serializes incoming `Data` into a `SerializedObject` value.
  929. ///
  930. /// - Parameter data: `Data` to be serialized.
  931. ///
  932. /// - Throws: Any error produced during serialization.
  933. func serialize(_ data: Data) throws -> SerializedObject
  934. }
  935. /// `DataStreamSerializer` which uses the provided `DataPreprocessor` and `DataDecoder` to serialize the incoming `Data`.
  936. public struct DecodableStreamSerializer<T: Decodable>: DataStreamSerializer {
  937. /// `DataDecoder` used to decode incoming `Data`.
  938. public let decoder: DataDecoder
  939. /// `DataPreprocessor` incoming `Data` is passed through before being passed to the `DataDecoder`.
  940. public let dataPreprocessor: DataPreprocessor
  941. /// Creates an instance with the provided `DataDecoder` and `DataPreprocessor`.
  942. /// - Parameters:
  943. /// - decoder: ` DataDecoder` used to decode incoming `Data`. `JSONDecoder()` by default.
  944. /// - dataPreprocessor: `DataPreprocessor` used to process incoming `Data` before it's passed through the
  945. /// `decoder`. `PassthroughPreprocessor()` by default.
  946. public init(decoder: DataDecoder = JSONDecoder(), dataPreprocessor: DataPreprocessor = PassthroughPreprocessor()) {
  947. self.decoder = decoder
  948. self.dataPreprocessor = dataPreprocessor
  949. }
  950. public func serialize(_ data: Data) throws -> T {
  951. let processedData = try dataPreprocessor.preprocess(data)
  952. do {
  953. return try decoder.decode(T.self, from: processedData)
  954. } catch {
  955. throw AFError.responseSerializationFailed(reason: .decodingFailed(error: error))
  956. }
  957. }
  958. }
  959. /// `DataStreamSerializer` which performs no serialization on incoming `Data`.
  960. public struct PassthroughStreamSerializer: DataStreamSerializer {
  961. /// Creates an instance.
  962. public init() {}
  963. public func serialize(_ data: Data) throws -> Data { data }
  964. }
  965. /// `DataStreamSerializer` which serializes incoming stream `Data` into `UTF8`-decoded `String` values.
  966. public struct StringStreamSerializer: DataStreamSerializer {
  967. /// Creates an instance.
  968. public init() {}
  969. public func serialize(_ data: Data) throws -> String {
  970. String(decoding: data, as: UTF8.self)
  971. }
  972. }
  973. extension DataStreamSerializer {
  974. /// Creates a `DecodableStreamSerializer` instance with the provided `DataDecoder` and `DataPreprocessor`.
  975. ///
  976. /// - Parameters:
  977. /// - type: `Decodable` type to decode from stream data.
  978. /// - decoder: ` DataDecoder` used to decode incoming `Data`. `JSONDecoder()` by default.
  979. /// - dataPreprocessor: `DataPreprocessor` used to process incoming `Data` before it's passed through the
  980. /// `decoder`. `PassthroughPreprocessor()` by default.
  981. public static func decodable<T: Decodable>(of type: T.Type,
  982. decoder: DataDecoder = JSONDecoder(),
  983. dataPreprocessor: DataPreprocessor = PassthroughPreprocessor()) -> Self where Self == DecodableStreamSerializer<T> {
  984. DecodableStreamSerializer<T>(decoder: decoder, dataPreprocessor: dataPreprocessor)
  985. }
  986. }
  987. extension DataStreamSerializer where Self == PassthroughStreamSerializer {
  988. /// Provides a `PassthroughStreamSerializer` instance.
  989. public static var passthrough: PassthroughStreamSerializer { PassthroughStreamSerializer() }
  990. }
  991. extension DataStreamSerializer where Self == StringStreamSerializer {
  992. /// Provides a `StringStreamSerializer` instance.
  993. public static var string: StringStreamSerializer { StringStreamSerializer() }
  994. }
  995. extension DataStreamRequest {
  996. /// Adds a `StreamHandler` which performs no parsing on incoming `Data`.
  997. ///
  998. /// - Parameters:
  999. /// - queue: `DispatchQueue` on which to perform `StreamHandler` closure.
  1000. /// - stream: `StreamHandler` closure called as `Data` is received. May be called multiple times.
  1001. ///
  1002. /// - Returns: The `DataStreamRequest`.
  1003. @discardableResult
  1004. public func responseStream(on queue: DispatchQueue = .main, stream: @escaping Handler<Data, Never>) -> Self {
  1005. let parser = { [unowned self] (data: Data) in
  1006. queue.async {
  1007. self.capturingError {
  1008. try stream(.init(event: .stream(.success(data)), token: .init(self)))
  1009. }
  1010. self.updateAndCompleteIfPossible()
  1011. }
  1012. }
  1013. streamMutableState.write { $0.streams.append(parser) }
  1014. appendStreamCompletion(on: queue, stream: stream)
  1015. return self
  1016. }
  1017. /// Adds a `StreamHandler` which uses the provided `DataStreamSerializer` to process incoming `Data`.
  1018. ///
  1019. /// - Parameters:
  1020. /// - serializer: `DataStreamSerializer` used to process incoming `Data`. Its work is done on the `serializationQueue`.
  1021. /// - queue: `DispatchQueue` on which to perform `StreamHandler` closure.
  1022. /// - stream: `StreamHandler` closure called as `Data` is received. May be called multiple times.
  1023. ///
  1024. /// - Returns: The `DataStreamRequest`.
  1025. @discardableResult
  1026. public func responseStream<Serializer: DataStreamSerializer>(using serializer: Serializer,
  1027. on queue: DispatchQueue = .main,
  1028. stream: @escaping Handler<Serializer.SerializedObject, AFError>) -> Self {
  1029. let parser = { [unowned self] (data: Data) in
  1030. serializationQueue.async {
  1031. // Start work on serialization queue.
  1032. let result = Result { try serializer.serialize(data) }
  1033. .mapError { $0.asAFError(or: .responseSerializationFailed(reason: .customSerializationFailed(error: $0))) }
  1034. // End work on serialization queue.
  1035. self.underlyingQueue.async {
  1036. self.eventMonitor?.request(self, didParseStream: result)
  1037. if result.isFailure, self.automaticallyCancelOnStreamError {
  1038. self.cancel()
  1039. }
  1040. queue.async {
  1041. self.capturingError {
  1042. try stream(.init(event: .stream(result), token: .init(self)))
  1043. }
  1044. self.updateAndCompleteIfPossible()
  1045. }
  1046. }
  1047. }
  1048. }
  1049. streamMutableState.write { $0.streams.append(parser) }
  1050. appendStreamCompletion(on: queue, stream: stream)
  1051. return self
  1052. }
  1053. /// Adds a `StreamHandler` which parses incoming `Data` as a UTF8 `String`.
  1054. ///
  1055. /// - Parameters:
  1056. /// - queue: `DispatchQueue` on which to perform `StreamHandler` closure.
  1057. /// - stream: `StreamHandler` closure called as `Data` is received. May be called multiple times.
  1058. ///
  1059. /// - Returns: The `DataStreamRequest`.
  1060. @discardableResult
  1061. public func responseStreamString(on queue: DispatchQueue = .main,
  1062. stream: @escaping Handler<String, Never>) -> Self {
  1063. let parser = { [unowned self] (data: Data) in
  1064. serializationQueue.async {
  1065. // Start work on serialization queue.
  1066. let string = String(decoding: data, as: UTF8.self)
  1067. // End work on serialization queue.
  1068. self.underlyingQueue.async {
  1069. self.eventMonitor?.request(self, didParseStream: .success(string))
  1070. queue.async {
  1071. self.capturingError {
  1072. try stream(.init(event: .stream(.success(string)), token: .init(self)))
  1073. }
  1074. self.updateAndCompleteIfPossible()
  1075. }
  1076. }
  1077. }
  1078. }
  1079. streamMutableState.write { $0.streams.append(parser) }
  1080. appendStreamCompletion(on: queue, stream: stream)
  1081. return self
  1082. }
  1083. private func updateAndCompleteIfPossible() {
  1084. streamMutableState.write { state in
  1085. state.numberOfExecutingStreams -= 1
  1086. guard state.numberOfExecutingStreams == 0, !state.enqueuedCompletionEvents.isEmpty else { return }
  1087. let completionEvents = state.enqueuedCompletionEvents
  1088. self.underlyingQueue.async { completionEvents.forEach { $0() } }
  1089. state.enqueuedCompletionEvents.removeAll()
  1090. }
  1091. }
  1092. /// Adds a `StreamHandler` which parses incoming `Data` using the provided `DataDecoder`.
  1093. ///
  1094. /// - Parameters:
  1095. /// - type: `Decodable` type to parse incoming `Data` into.
  1096. /// - queue: `DispatchQueue` on which to perform `StreamHandler` closure.
  1097. /// - decoder: `DataDecoder` used to decode the incoming `Data`.
  1098. /// - preprocessor: `DataPreprocessor` used to process the incoming `Data` before it's passed to the `decoder`.
  1099. /// - stream: `StreamHandler` closure called as `Data` is received. May be called multiple times.
  1100. ///
  1101. /// - Returns: The `DataStreamRequest`.
  1102. @discardableResult
  1103. public func responseStreamDecodable<T: Decodable>(of type: T.Type = T.self,
  1104. on queue: DispatchQueue = .main,
  1105. using decoder: DataDecoder = JSONDecoder(),
  1106. preprocessor: DataPreprocessor = PassthroughPreprocessor(),
  1107. stream: @escaping Handler<T, AFError>) -> Self {
  1108. responseStream(using: DecodableStreamSerializer<T>(decoder: decoder, dataPreprocessor: preprocessor),
  1109. stream: stream)
  1110. }
  1111. }