ResponseSerialization.swift 67 KB

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