AutorÃa | Ultima modificación | Ver Log |
//// ResponseSerialization.swift//// Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/)//// Permission is hereby granted, free of charge, to any person obtaining a copy// of this software and associated documentation files (the "Software"), to deal// in the Software without restriction, including without limitation the rights// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell// copies of the Software, and to permit persons to whom the Software is// furnished to do so, subject to the following conditions://// The above copyright notice and this permission notice shall be included in// all copies or substantial portions of the Software.//// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN// THE SOFTWARE.//import Foundation// MARK: Protocols/// The type to which all data response serializers must conform in order to serialize a response.public protocol DataResponseSerializerProtocol {/// The type of serialized object to be created.associatedtype SerializedObject/// Serialize the response `Data` into the provided type..////// - Parameters:/// - request: `URLRequest` which was used to perform the request, if any./// - response: `HTTPURLResponse` received from the server, if any./// - data: `Data` returned from the server, if any./// - error: `Error` produced by Alamofire or the underlying `URLSession` during the request.////// - Returns: The `SerializedObject`./// - Throws: Any `Error` produced during serialization.func serialize(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?) throws -> SerializedObject}/// The type to which all download response serializers must conform in order to serialize a response.public protocol DownloadResponseSerializerProtocol {/// The type of serialized object to be created.associatedtype SerializedObject/// Serialize the downloaded response `Data` from disk into the provided type..////// - Parameters:/// - request: `URLRequest` which was used to perform the request, if any./// - response: `HTTPURLResponse` received from the server, if any./// - fileURL: File `URL` to which the response data was downloaded./// - error: `Error` produced by Alamofire or the underlying `URLSession` during the request.////// - Returns: The `SerializedObject`./// - Throws: Any `Error` produced during serialization.func serializeDownload(request: URLRequest?, response: HTTPURLResponse?, fileURL: URL?, error: Error?) throws -> SerializedObject}/// A serializer that can handle both data and download responses.public protocol ResponseSerializer: DataResponseSerializerProtocol & DownloadResponseSerializerProtocol {/// `DataPreprocessor` used to prepare incoming `Data` for serialization.var dataPreprocessor: DataPreprocessor { get }/// `HTTPMethod`s for which empty response bodies are considered appropriate.var emptyRequestMethods: Set<HTTPMethod> { get }/// HTTP response codes for which empty response bodies are considered appropriate.var emptyResponseCodes: Set<Int> { get }}/// Type used to preprocess `Data` before it handled by a serializer.public protocol DataPreprocessor {/// Process `Data` before it's handled by a serializer./// - Parameter data: The raw `Data` to process.func preprocess(_ data: Data) throws -> Data}/// `DataPreprocessor` that returns passed `Data` without any transform.public struct PassthroughPreprocessor: DataPreprocessor {public init() {}public func preprocess(_ data: Data) throws -> Data { data }}/// `DataPreprocessor` that trims Google's typical `)]}',\n` XSSI JSON header.public struct GoogleXSSIPreprocessor: DataPreprocessor {public init() {}public func preprocess(_ data: Data) throws -> Data {(data.prefix(6) == Data(")]}',\n".utf8)) ? data.dropFirst(6) : data}}#if swift(>=5.5)extension DataPreprocessor where Self == PassthroughPreprocessor {/// Provides a `PassthroughPreprocessor` instance.public static var passthrough: PassthroughPreprocessor { PassthroughPreprocessor() }}extension DataPreprocessor where Self == GoogleXSSIPreprocessor {/// Provides a `GoogleXSSIPreprocessor` instance.public static var googleXSSI: GoogleXSSIPreprocessor { GoogleXSSIPreprocessor() }}#endifextension ResponseSerializer {/// Default `DataPreprocessor`. `PassthroughPreprocessor` by default.public static var defaultDataPreprocessor: DataPreprocessor { PassthroughPreprocessor() }/// Default `HTTPMethod`s for which empty response bodies are considered appropriate. `[.head]` by default.public static var defaultEmptyRequestMethods: Set<HTTPMethod> { [.head] }/// HTTP response codes for which empty response bodies are considered appropriate. `[204, 205]` by default.public static var defaultEmptyResponseCodes: Set<Int> { [204, 205] }public var dataPreprocessor: DataPreprocessor { Self.defaultDataPreprocessor }public var emptyRequestMethods: Set<HTTPMethod> { Self.defaultEmptyRequestMethods }public var emptyResponseCodes: Set<Int> { Self.defaultEmptyResponseCodes }/// Determines whether the `request` allows empty response bodies, if `request` exists.////// - Parameter request: `URLRequest` to evaluate.////// - Returns: `Bool` representing the outcome of the evaluation, or `nil` if `request` was `nil`.public func requestAllowsEmptyResponseData(_ request: URLRequest?) -> Bool? {request.flatMap(\.httpMethod).flatMap(HTTPMethod.init).map { emptyRequestMethods.contains($0) }}/// Determines whether the `response` allows empty response bodies, if `response` exists`.////// - Parameter response: `HTTPURLResponse` to evaluate.////// - Returns: `Bool` representing the outcome of the evaluation, or `nil` if `response` was `nil`.public func responseAllowsEmptyResponseData(_ response: HTTPURLResponse?) -> Bool? {response.map(\.statusCode).map { emptyResponseCodes.contains($0) }}/// Determines whether `request` and `response` allow empty response bodies.////// - Parameters:/// - request: `URLRequest` to evaluate./// - response: `HTTPURLResponse` to evaluate.////// - Returns: `true` if `request` or `response` allow empty bodies, `false` otherwise.public func emptyResponseAllowed(forRequest request: URLRequest?, response: HTTPURLResponse?) -> Bool {(requestAllowsEmptyResponseData(request) == true) || (responseAllowsEmptyResponseData(response) == true)}}/// By default, any serializer declared to conform to both types will get file serialization for free, as it just feeds/// the data read from disk into the data response serializer.extension DownloadResponseSerializerProtocol where Self: DataResponseSerializerProtocol {public func serializeDownload(request: URLRequest?, response: HTTPURLResponse?, fileURL: URL?, error: Error?) throws -> Self.SerializedObject {guard error == nil else { throw error! }guard let fileURL = fileURL else {throw AFError.responseSerializationFailed(reason: .inputFileNil)}let data: Datado {data = try Data(contentsOf: fileURL)} catch {throw AFError.responseSerializationFailed(reason: .inputFileReadFailed(at: fileURL))}do {return try serialize(request: request, response: response, data: data, error: error)} catch {throw error}}}// MARK: - Defaultextension DataRequest {/// Adds a handler to be called once the request has finished.////// - Parameters:/// - queue: The queue on which the completion handler is dispatched. `.main` by default./// - completionHandler: The code to be executed once the request has finished.////// - Returns: The request.@discardableResultpublic func response(queue: DispatchQueue = .main, completionHandler: @escaping (AFDataResponse<Data?>) -> Void) -> Self {appendResponseSerializer {// Start work that should be on the serialization queue.let result = AFResult<Data?>(value: self.data, error: self.error)// End work that should be on the serialization queue.self.underlyingQueue.async {let response = DataResponse(request: self.request,response: self.response,data: self.data,metrics: self.metrics,serializationDuration: 0,result: result)self.eventMonitor?.request(self, didParseResponse: response)self.responseSerializerDidComplete { queue.async { completionHandler(response) } }}}return self}private func _response<Serializer: DataResponseSerializerProtocol>(queue: DispatchQueue = .main,responseSerializer: Serializer,completionHandler: @escaping (AFDataResponse<Serializer.SerializedObject>) -> Void)-> Self {appendResponseSerializer {// Start work that should be on the serialization queue.let start = ProcessInfo.processInfo.systemUptimelet result: AFResult<Serializer.SerializedObject> = Result {try responseSerializer.serialize(request: self.request,response: self.response,data: self.data,error: self.error)}.mapError { error inerror.asAFError(or: .responseSerializationFailed(reason: .customSerializationFailed(error: error)))}let end = ProcessInfo.processInfo.systemUptime// End work that should be on the serialization queue.self.underlyingQueue.async {let response = DataResponse(request: self.request,response: self.response,data: self.data,metrics: self.metrics,serializationDuration: end - start,result: result)self.eventMonitor?.request(self, didParseResponse: response)guard let serializerError = result.failure, let delegate = self.delegate else {self.responseSerializerDidComplete { queue.async { completionHandler(response) } }return}delegate.retryResult(for: self, dueTo: serializerError) { retryResult invar didComplete: (() -> Void)?defer {if let didComplete = didComplete {self.responseSerializerDidComplete { queue.async { didComplete() } }}}switch retryResult {case .doNotRetry:didComplete = { completionHandler(response) }case let .doNotRetryWithError(retryError):let result: AFResult<Serializer.SerializedObject> = .failure(retryError.asAFError(orFailWith: "Received retryError was not already AFError"))let response = DataResponse(request: self.request,response: self.response,data: self.data,metrics: self.metrics,serializationDuration: end - start,result: result)didComplete = { completionHandler(response) }case .retry, .retryWithDelay:delegate.retryRequest(self, withDelay: retryResult.delay)}}}}return self}/// Adds a handler to be called once the request has finished.////// - Parameters:/// - queue: The queue on which the completion handler is dispatched. `.main` by default/// - responseSerializer: The response serializer responsible for serializing the request, response, and data./// - completionHandler: The code to be executed once the request has finished.////// - Returns: The request.@discardableResultpublic func response<Serializer: DataResponseSerializerProtocol>(queue: DispatchQueue = .main,responseSerializer: Serializer,completionHandler: @escaping (AFDataResponse<Serializer.SerializedObject>) -> Void)-> Self {_response(queue: queue, responseSerializer: responseSerializer, completionHandler: completionHandler)}/// Adds a handler to be called once the request has finished.////// - Parameters:/// - queue: The queue on which the completion handler is dispatched. `.main` by default/// - responseSerializer: The response serializer responsible for serializing the request, response, and data./// - completionHandler: The code to be executed once the request has finished.////// - Returns: The request.@discardableResultpublic func response<Serializer: ResponseSerializer>(queue: DispatchQueue = .main,responseSerializer: Serializer,completionHandler: @escaping (AFDataResponse<Serializer.SerializedObject>) -> Void)-> Self {_response(queue: queue, responseSerializer: responseSerializer, completionHandler: completionHandler)}}extension DownloadRequest {/// Adds a handler to be called once the request has finished.////// - Parameters:/// - queue: The queue on which the completion handler is dispatched. `.main` by default./// - completionHandler: The code to be executed once the request has finished.////// - Returns: The request.@discardableResultpublic func response(queue: DispatchQueue = .main,completionHandler: @escaping (AFDownloadResponse<URL?>) -> Void)-> Self {appendResponseSerializer {// Start work that should be on the serialization queue.let result = AFResult<URL?>(value: self.fileURL, error: self.error)// End work that should be on the serialization queue.self.underlyingQueue.async {let response = DownloadResponse(request: self.request,response: self.response,fileURL: self.fileURL,resumeData: self.resumeData,metrics: self.metrics,serializationDuration: 0,result: result)self.eventMonitor?.request(self, didParseResponse: response)self.responseSerializerDidComplete { queue.async { completionHandler(response) } }}}return self}private func _response<Serializer: DownloadResponseSerializerProtocol>(queue: DispatchQueue = .main,responseSerializer: Serializer,completionHandler: @escaping (AFDownloadResponse<Serializer.SerializedObject>) -> Void)-> Self {appendResponseSerializer {// Start work that should be on the serialization queue.let start = ProcessInfo.processInfo.systemUptimelet result: AFResult<Serializer.SerializedObject> = Result {try responseSerializer.serializeDownload(request: self.request,response: self.response,fileURL: self.fileURL,error: self.error)}.mapError { error inerror.asAFError(or: .responseSerializationFailed(reason: .customSerializationFailed(error: error)))}let end = ProcessInfo.processInfo.systemUptime// End work that should be on the serialization queue.self.underlyingQueue.async {let response = DownloadResponse(request: self.request,response: self.response,fileURL: self.fileURL,resumeData: self.resumeData,metrics: self.metrics,serializationDuration: end - start,result: result)self.eventMonitor?.request(self, didParseResponse: response)guard let serializerError = result.failure, let delegate = self.delegate else {self.responseSerializerDidComplete { queue.async { completionHandler(response) } }return}delegate.retryResult(for: self, dueTo: serializerError) { retryResult invar didComplete: (() -> Void)?defer {if let didComplete = didComplete {self.responseSerializerDidComplete { queue.async { didComplete() } }}}switch retryResult {case .doNotRetry:didComplete = { completionHandler(response) }case let .doNotRetryWithError(retryError):let result: AFResult<Serializer.SerializedObject> = .failure(retryError.asAFError(orFailWith: "Received retryError was not already AFError"))let response = DownloadResponse(request: self.request,response: self.response,fileURL: self.fileURL,resumeData: self.resumeData,metrics: self.metrics,serializationDuration: end - start,result: result)didComplete = { completionHandler(response) }case .retry, .retryWithDelay:delegate.retryRequest(self, withDelay: retryResult.delay)}}}}return self}/// Adds a handler to be called once the request has finished.////// - Parameters:/// - queue: The queue on which the completion handler is dispatched. `.main` by default./// - responseSerializer: The response serializer responsible for serializing the request, response, and data/// contained in the destination `URL`./// - completionHandler: The code to be executed once the request has finished.////// - Returns: The request.@discardableResultpublic func response<Serializer: DownloadResponseSerializerProtocol>(queue: DispatchQueue = .main,responseSerializer: Serializer,completionHandler: @escaping (AFDownloadResponse<Serializer.SerializedObject>) -> Void)-> Self {_response(queue: queue, responseSerializer: responseSerializer, completionHandler: completionHandler)}/// Adds a handler to be called once the request has finished.////// - Parameters:/// - queue: The queue on which the completion handler is dispatched. `.main` by default./// - responseSerializer: The response serializer responsible for serializing the request, response, and data/// contained in the destination `URL`./// - completionHandler: The code to be executed once the request has finished.////// - Returns: The request.@discardableResultpublic func response<Serializer: ResponseSerializer>(queue: DispatchQueue = .main,responseSerializer: Serializer,completionHandler: @escaping (AFDownloadResponse<Serializer.SerializedObject>) -> Void)-> Self {_response(queue: queue, responseSerializer: responseSerializer, completionHandler: completionHandler)}}// MARK: - URL/// A `DownloadResponseSerializerProtocol` that performs only `Error` checking and ensures that a downloaded `fileURL`/// is present.public struct URLResponseSerializer: DownloadResponseSerializerProtocol {/// Creates an instance.public init() {}public func serializeDownload(request: URLRequest?,response: HTTPURLResponse?,fileURL: URL?,error: Error?) throws -> URL {guard error == nil else { throw error! }guard let url = fileURL else {throw AFError.responseSerializationFailed(reason: .inputFileNil)}return url}}#if swift(>=5.5)extension DownloadResponseSerializerProtocol where Self == URLResponseSerializer {/// Provides a `URLResponseSerializer` instance.public static var url: URLResponseSerializer { URLResponseSerializer() }}#endifextension DownloadRequest {/// Adds a handler using a `URLResponseSerializer` to be called once the request is finished.////// - Parameters:/// - queue: The queue on which the completion handler is called. `.main` by default./// - completionHandler: A closure to be executed once the request has finished.////// - Returns: The request.@discardableResultpublic func responseURL(queue: DispatchQueue = .main,completionHandler: @escaping (AFDownloadResponse<URL>) -> Void) -> Self {response(queue: queue, responseSerializer: URLResponseSerializer(), completionHandler: completionHandler)}}// MARK: - Data/// A `ResponseSerializer` that performs minimal response checking and returns any response `Data` as-is. By default, a/// request returning `nil` or no data is considered an error. However, if the request has an `HTTPMethod` or the/// response has an HTTP status code valid for empty responses, then an empty `Data` value is returned.public final class DataResponseSerializer: ResponseSerializer {public let dataPreprocessor: DataPreprocessorpublic let emptyResponseCodes: Set<Int>public let emptyRequestMethods: Set<HTTPMethod>/// Creates a `DataResponseSerializer` using the provided parameters.////// - Parameters:/// - dataPreprocessor: `DataPreprocessor` used to prepare the received `Data` for serialization./// - emptyResponseCodes: The HTTP response codes for which empty responses are allowed. `[204, 205]` by default./// - emptyRequestMethods: The HTTP request methods for which empty responses are allowed. `[.head]` by default.public init(dataPreprocessor: DataPreprocessor = DataResponseSerializer.defaultDataPreprocessor,emptyResponseCodes: Set<Int> = DataResponseSerializer.defaultEmptyResponseCodes,emptyRequestMethods: Set<HTTPMethod> = DataResponseSerializer.defaultEmptyRequestMethods) {self.dataPreprocessor = dataPreprocessorself.emptyResponseCodes = emptyResponseCodesself.emptyRequestMethods = emptyRequestMethods}public func serialize(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?) throws -> Data {guard error == nil else { throw error! }guard var data = data, !data.isEmpty else {guard emptyResponseAllowed(forRequest: request, response: response) else {throw AFError.responseSerializationFailed(reason: .inputDataNilOrZeroLength)}return Data()}data = try dataPreprocessor.preprocess(data)return data}}#if swift(>=5.5)extension ResponseSerializer where Self == DataResponseSerializer {/// Provides a default `DataResponseSerializer` instance.public static var data: DataResponseSerializer { DataResponseSerializer() }/// Creates a `DataResponseSerializer` using the provided parameters.////// - Parameters:/// - dataPreprocessor: `DataPreprocessor` used to prepare the received `Data` for serialization./// - emptyResponseCodes: The HTTP response codes for which empty responses are allowed. `[204, 205]` by default./// - emptyRequestMethods: The HTTP request methods for which empty responses are allowed. `[.head]` by default.////// - Returns: The `DataResponseSerializer`.public static func data(dataPreprocessor: DataPreprocessor = DataResponseSerializer.defaultDataPreprocessor,emptyResponseCodes: Set<Int> = DataResponseSerializer.defaultEmptyResponseCodes,emptyRequestMethods: Set<HTTPMethod> = DataResponseSerializer.defaultEmptyRequestMethods) -> DataResponseSerializer {DataResponseSerializer(dataPreprocessor: dataPreprocessor,emptyResponseCodes: emptyResponseCodes,emptyRequestMethods: emptyRequestMethods)}}#endifextension DataRequest {/// Adds a handler using a `DataResponseSerializer` to be called once the request has finished.////// - Parameters:/// - queue: The queue on which the completion handler is called. `.main` by default./// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the/// `completionHandler`. `PassthroughPreprocessor()` by default./// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default./// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default./// - completionHandler: A closure to be executed once the request has finished.////// - Returns: The request.@discardableResultpublic func responseData(queue: DispatchQueue = .main,dataPreprocessor: DataPreprocessor = DataResponseSerializer.defaultDataPreprocessor,emptyResponseCodes: Set<Int> = DataResponseSerializer.defaultEmptyResponseCodes,emptyRequestMethods: Set<HTTPMethod> = DataResponseSerializer.defaultEmptyRequestMethods,completionHandler: @escaping (AFDataResponse<Data>) -> Void) -> Self {response(queue: queue,responseSerializer: DataResponseSerializer(dataPreprocessor: dataPreprocessor,emptyResponseCodes: emptyResponseCodes,emptyRequestMethods: emptyRequestMethods),completionHandler: completionHandler)}}extension DownloadRequest {/// Adds a handler using a `DataResponseSerializer` to be called once the request has finished.////// - Parameters:/// - queue: The queue on which the completion handler is called. `.main` by default./// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the/// `completionHandler`. `PassthroughPreprocessor()` by default./// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default./// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default./// - completionHandler: A closure to be executed once the request has finished.////// - Returns: The request.@discardableResultpublic func responseData(queue: DispatchQueue = .main,dataPreprocessor: DataPreprocessor = DataResponseSerializer.defaultDataPreprocessor,emptyResponseCodes: Set<Int> = DataResponseSerializer.defaultEmptyResponseCodes,emptyRequestMethods: Set<HTTPMethod> = DataResponseSerializer.defaultEmptyRequestMethods,completionHandler: @escaping (AFDownloadResponse<Data>) -> Void) -> Self {response(queue: queue,responseSerializer: DataResponseSerializer(dataPreprocessor: dataPreprocessor,emptyResponseCodes: emptyResponseCodes,emptyRequestMethods: emptyRequestMethods),completionHandler: completionHandler)}}// MARK: - String/// A `ResponseSerializer` that decodes the response data as a `String`. By default, a request returning `nil` or no/// data is considered an error. However, if the request has an `HTTPMethod` or the response has an HTTP status code/// valid for empty responses, then an empty `String` is returned.public final class StringResponseSerializer: ResponseSerializer {public let dataPreprocessor: DataPreprocessor/// Optional string encoding used to validate the response.public let encoding: String.Encoding?public let emptyResponseCodes: Set<Int>public let emptyRequestMethods: Set<HTTPMethod>/// Creates an instance with the provided values.////// - Parameters:/// - dataPreprocessor: `DataPreprocessor` used to prepare the received `Data` for serialization./// - encoding: A string encoding. Defaults to `nil`, in which case the encoding will be determined/// from the server response, falling back to the default HTTP character set, `ISO-8859-1`./// - emptyResponseCodes: The HTTP response codes for which empty responses are allowed. `[204, 205]` by default./// - emptyRequestMethods: The HTTP request methods for which empty responses are allowed. `[.head]` by default.public init(dataPreprocessor: DataPreprocessor = StringResponseSerializer.defaultDataPreprocessor,encoding: String.Encoding? = nil,emptyResponseCodes: Set<Int> = StringResponseSerializer.defaultEmptyResponseCodes,emptyRequestMethods: Set<HTTPMethod> = StringResponseSerializer.defaultEmptyRequestMethods) {self.dataPreprocessor = dataPreprocessorself.encoding = encodingself.emptyResponseCodes = emptyResponseCodesself.emptyRequestMethods = emptyRequestMethods}public func serialize(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?) throws -> String {guard error == nil else { throw error! }guard var data = data, !data.isEmpty else {guard emptyResponseAllowed(forRequest: request, response: response) else {throw AFError.responseSerializationFailed(reason: .inputDataNilOrZeroLength)}return ""}data = try dataPreprocessor.preprocess(data)var convertedEncoding = encodingif let encodingName = response?.textEncodingName, convertedEncoding == nil {convertedEncoding = String.Encoding(ianaCharsetName: encodingName)}let actualEncoding = convertedEncoding ?? .isoLatin1guard let string = String(data: data, encoding: actualEncoding) else {throw AFError.responseSerializationFailed(reason: .stringSerializationFailed(encoding: actualEncoding))}return string}}#if swift(>=5.5)extension ResponseSerializer where Self == StringResponseSerializer {/// Provides a default `StringResponseSerializer` instance.public static var string: StringResponseSerializer { StringResponseSerializer() }/// Creates a `StringResponseSerializer` with the provided values.////// - Parameters:/// - dataPreprocessor: `DataPreprocessor` used to prepare the received `Data` for serialization./// - encoding: A string encoding. Defaults to `nil`, in which case the encoding will be determined/// from the server response, falling back to the default HTTP character set, `ISO-8859-1`./// - emptyResponseCodes: The HTTP response codes for which empty responses are allowed. `[204, 205]` by default./// - emptyRequestMethods: The HTTP request methods for which empty responses are allowed. `[.head]` by default.////// - Returns: The `StringResponseSerializer`.public static func string(dataPreprocessor: DataPreprocessor = StringResponseSerializer.defaultDataPreprocessor,encoding: String.Encoding? = nil,emptyResponseCodes: Set<Int> = StringResponseSerializer.defaultEmptyResponseCodes,emptyRequestMethods: Set<HTTPMethod> = StringResponseSerializer.defaultEmptyRequestMethods) -> StringResponseSerializer {StringResponseSerializer(dataPreprocessor: dataPreprocessor,encoding: encoding,emptyResponseCodes: emptyResponseCodes,emptyRequestMethods: emptyRequestMethods)}}#endifextension DataRequest {/// Adds a handler using a `StringResponseSerializer` to be called once the request has finished.////// - Parameters:/// - queue: The queue on which the completion handler is dispatched. `.main` by default./// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the/// `completionHandler`. `PassthroughPreprocessor()` by default./// - encoding: The string encoding. Defaults to `nil`, in which case the encoding will be determined/// from the server response, falling back to the default HTTP character set, `ISO-8859-1`./// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default./// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default./// - completionHandler: A closure to be executed once the request has finished.////// - Returns: The request.@discardableResultpublic func responseString(queue: DispatchQueue = .main,dataPreprocessor: DataPreprocessor = StringResponseSerializer.defaultDataPreprocessor,encoding: String.Encoding? = nil,emptyResponseCodes: Set<Int> = StringResponseSerializer.defaultEmptyResponseCodes,emptyRequestMethods: Set<HTTPMethod> = StringResponseSerializer.defaultEmptyRequestMethods,completionHandler: @escaping (AFDataResponse<String>) -> Void) -> Self {response(queue: queue,responseSerializer: StringResponseSerializer(dataPreprocessor: dataPreprocessor,encoding: encoding,emptyResponseCodes: emptyResponseCodes,emptyRequestMethods: emptyRequestMethods),completionHandler: completionHandler)}}extension DownloadRequest {/// Adds a handler using a `StringResponseSerializer` to be called once the request has finished.////// - Parameters:/// - queue: The queue on which the completion handler is dispatched. `.main` by default./// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the/// `completionHandler`. `PassthroughPreprocessor()` by default./// - encoding: The string encoding. Defaults to `nil`, in which case the encoding will be determined/// from the server response, falling back to the default HTTP character set, `ISO-8859-1`./// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default./// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default./// - completionHandler: A closure to be executed once the request has finished.////// - Returns: The request.@discardableResultpublic func responseString(queue: DispatchQueue = .main,dataPreprocessor: DataPreprocessor = StringResponseSerializer.defaultDataPreprocessor,encoding: String.Encoding? = nil,emptyResponseCodes: Set<Int> = StringResponseSerializer.defaultEmptyResponseCodes,emptyRequestMethods: Set<HTTPMethod> = StringResponseSerializer.defaultEmptyRequestMethods,completionHandler: @escaping (AFDownloadResponse<String>) -> Void) -> Self {response(queue: queue,responseSerializer: StringResponseSerializer(dataPreprocessor: dataPreprocessor,encoding: encoding,emptyResponseCodes: emptyResponseCodes,emptyRequestMethods: emptyRequestMethods),completionHandler: completionHandler)}}// MARK: - JSON/// A `ResponseSerializer` that decodes the response data using `JSONSerialization`. By default, a request returning/// `nil` or no data is considered an error. However, if the request has an `HTTPMethod` or the response has an/// HTTP status code valid for empty responses, then an `NSNull` value is returned.@available(*, deprecated, message: "JSONResponseSerializer deprecated and will be removed in Alamofire 6. Use DecodableResponseSerializer instead.")public final class JSONResponseSerializer: ResponseSerializer {public let dataPreprocessor: DataPreprocessorpublic let emptyResponseCodes: Set<Int>public let emptyRequestMethods: Set<HTTPMethod>/// `JSONSerialization.ReadingOptions` used when serializing a response.public let options: JSONSerialization.ReadingOptions/// Creates an instance with the provided values.////// - Parameters:/// - dataPreprocessor: `DataPreprocessor` used to prepare the received `Data` for serialization./// - emptyResponseCodes: The HTTP response codes for which empty responses are allowed. `[204, 205]` by default./// - emptyRequestMethods: The HTTP request methods for which empty responses are allowed. `[.head]` by default./// - options: The options to use. `.allowFragments` by default.public init(dataPreprocessor: DataPreprocessor = JSONResponseSerializer.defaultDataPreprocessor,emptyResponseCodes: Set<Int> = JSONResponseSerializer.defaultEmptyResponseCodes,emptyRequestMethods: Set<HTTPMethod> = JSONResponseSerializer.defaultEmptyRequestMethods,options: JSONSerialization.ReadingOptions = .allowFragments) {self.dataPreprocessor = dataPreprocessorself.emptyResponseCodes = emptyResponseCodesself.emptyRequestMethods = emptyRequestMethodsself.options = options}public func serialize(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?) throws -> Any {guard error == nil else { throw error! }guard var data = data, !data.isEmpty else {guard emptyResponseAllowed(forRequest: request, response: response) else {throw AFError.responseSerializationFailed(reason: .inputDataNilOrZeroLength)}return NSNull()}data = try dataPreprocessor.preprocess(data)do {return try JSONSerialization.jsonObject(with: data, options: options)} catch {throw AFError.responseSerializationFailed(reason: .jsonSerializationFailed(error: error))}}}extension DataRequest {/// Adds a handler using a `JSONResponseSerializer` to be called once the request has finished.////// - Parameters:/// - queue: The queue on which the completion handler is dispatched. `.main` by default./// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the/// `completionHandler`. `PassthroughPreprocessor()` by default./// - encoding: The string encoding. Defaults to `nil`, in which case the encoding will be determined/// from the server response, falling back to the default HTTP character set, `ISO-8859-1`./// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default./// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default./// - options: `JSONSerialization.ReadingOptions` used when parsing the response. `.allowFragments`/// by default./// - completionHandler: A closure to be executed once the request has finished.////// - Returns: The request.@available(*, deprecated, message: "responseJSON deprecated and will be removed in Alamofire 6. Use responseDecodable instead.")@discardableResultpublic func responseJSON(queue: DispatchQueue = .main,dataPreprocessor: DataPreprocessor = JSONResponseSerializer.defaultDataPreprocessor,emptyResponseCodes: Set<Int> = JSONResponseSerializer.defaultEmptyResponseCodes,emptyRequestMethods: Set<HTTPMethod> = JSONResponseSerializer.defaultEmptyRequestMethods,options: JSONSerialization.ReadingOptions = .allowFragments,completionHandler: @escaping (AFDataResponse<Any>) -> Void) -> Self {response(queue: queue,responseSerializer: JSONResponseSerializer(dataPreprocessor: dataPreprocessor,emptyResponseCodes: emptyResponseCodes,emptyRequestMethods: emptyRequestMethods,options: options),completionHandler: completionHandler)}}extension DownloadRequest {/// Adds a handler using a `JSONResponseSerializer` to be called once the request has finished.////// - Parameters:/// - queue: The queue on which the completion handler is dispatched. `.main` by default./// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the/// `completionHandler`. `PassthroughPreprocessor()` by default./// - encoding: The string encoding. Defaults to `nil`, in which case the encoding will be determined/// from the server response, falling back to the default HTTP character set, `ISO-8859-1`./// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default./// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default./// - options: `JSONSerialization.ReadingOptions` used when parsing the response. `.allowFragments`/// by default./// - completionHandler: A closure to be executed once the request has finished.////// - Returns: The request.@available(*, deprecated, message: "responseJSON deprecated and will be removed in Alamofire 6. Use responseDecodable instead.")@discardableResultpublic func responseJSON(queue: DispatchQueue = .main,dataPreprocessor: DataPreprocessor = JSONResponseSerializer.defaultDataPreprocessor,emptyResponseCodes: Set<Int> = JSONResponseSerializer.defaultEmptyResponseCodes,emptyRequestMethods: Set<HTTPMethod> = JSONResponseSerializer.defaultEmptyRequestMethods,options: JSONSerialization.ReadingOptions = .allowFragments,completionHandler: @escaping (AFDownloadResponse<Any>) -> Void) -> Self {response(queue: queue,responseSerializer: JSONResponseSerializer(dataPreprocessor: dataPreprocessor,emptyResponseCodes: emptyResponseCodes,emptyRequestMethods: emptyRequestMethods,options: options),completionHandler: completionHandler)}}// MARK: - Empty/// Protocol representing an empty response. Use `T.emptyValue()` to get an instance.public protocol EmptyResponse {/// Empty value for the conforming type.////// - Returns: Value of `Self` to use for empty values.static func emptyValue() -> Self}/// Type representing an empty value. Use `Empty.value` to get the static instance.public struct Empty: Codable {/// Static `Empty` instance used for all `Empty` responses.public static let value = Empty()}extension Empty: EmptyResponse {public static func emptyValue() -> Empty {value}}// MARK: - DataDecoder Protocol/// Any type which can decode `Data` into a `Decodable` type.public protocol DataDecoder {/// Decode `Data` into the provided type.////// - Parameters:/// - type: The `Type` to be decoded./// - data: The `Data` to be decoded.////// - Returns: The decoded value of type `D`./// - Throws: Any error that occurs during decode.func decode<D: Decodable>(_ type: D.Type, from data: Data) throws -> D}/// `JSONDecoder` automatically conforms to `DataDecoder`.extension JSONDecoder: DataDecoder {}/// `PropertyListDecoder` automatically conforms to `DataDecoder`.extension PropertyListDecoder: DataDecoder {}// MARK: - Decodable/// A `ResponseSerializer` that decodes the response data as a generic value using any type that conforms to/// `DataDecoder`. By default, this is an instance of `JSONDecoder`. Additionally, a request returning `nil` or no data/// is considered an error. However, if the request has an `HTTPMethod` or the response has an HTTP status code valid/// for empty responses then an empty value will be returned. If the decoded type conforms to `EmptyResponse`, the/// type's `emptyValue()` will be returned. If the decoded type is `Empty`, the `.value` instance is returned. If the/// decoded type *does not* conform to `EmptyResponse` and isn't `Empty`, an error will be produced.public final class DecodableResponseSerializer<T: Decodable>: ResponseSerializer {public let dataPreprocessor: DataPreprocessor/// The `DataDecoder` instance used to decode responses.public let decoder: DataDecoderpublic let emptyResponseCodes: Set<Int>public let emptyRequestMethods: Set<HTTPMethod>/// Creates an instance using the values provided.////// - Parameters:/// - dataPreprocessor: `DataPreprocessor` used to prepare the received `Data` for serialization./// - decoder: The `DataDecoder`. `JSONDecoder()` by default./// - emptyResponseCodes: The HTTP response codes for which empty responses are allowed. `[204, 205]` by default./// - emptyRequestMethods: The HTTP request methods for which empty responses are allowed. `[.head]` by default.public init(dataPreprocessor: DataPreprocessor = DecodableResponseSerializer.defaultDataPreprocessor,decoder: DataDecoder = JSONDecoder(),emptyResponseCodes: Set<Int> = DecodableResponseSerializer.defaultEmptyResponseCodes,emptyRequestMethods: Set<HTTPMethod> = DecodableResponseSerializer.defaultEmptyRequestMethods) {self.dataPreprocessor = dataPreprocessorself.decoder = decoderself.emptyResponseCodes = emptyResponseCodesself.emptyRequestMethods = emptyRequestMethods}public func serialize(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?) throws -> T {guard error == nil else { throw error! }guard var data = data, !data.isEmpty else {guard emptyResponseAllowed(forRequest: request, response: response) else {throw AFError.responseSerializationFailed(reason: .inputDataNilOrZeroLength)}guard let emptyResponseType = T.self as? EmptyResponse.Type, let emptyValue = emptyResponseType.emptyValue() as? T else {throw AFError.responseSerializationFailed(reason: .invalidEmptyResponse(type: "\(T.self)"))}return emptyValue}data = try dataPreprocessor.preprocess(data)do {return try decoder.decode(T.self, from: data)} catch {throw AFError.responseSerializationFailed(reason: .decodingFailed(error: error))}}}#if swift(>=5.5)extension ResponseSerializer {/// Creates a `DecodableResponseSerializer` using the values provided.////// - Parameters:/// - type: `Decodable` type to decode from response data./// - dataPreprocessor: `DataPreprocessor` used to prepare the received `Data` for serialization./// - decoder: The `DataDecoder`. `JSONDecoder()` by default./// - emptyResponseCodes: The HTTP response codes for which empty responses are allowed. `[204, 205]` by default./// - emptyRequestMethods: The HTTP request methods for which empty responses are allowed. `[.head]` by default.////// - Returns: The `DecodableResponseSerializer`.public static func decodable<T: Decodable>(of type: T.Type,dataPreprocessor: DataPreprocessor = DecodableResponseSerializer<T>.defaultDataPreprocessor,decoder: DataDecoder = JSONDecoder(),emptyResponseCodes: Set<Int> = DecodableResponseSerializer<T>.defaultEmptyResponseCodes,emptyRequestMethods: Set<HTTPMethod> = DecodableResponseSerializer<T>.defaultEmptyRequestMethods) -> DecodableResponseSerializer<T> where Self == DecodableResponseSerializer<T> {DecodableResponseSerializer<T>(dataPreprocessor: dataPreprocessor,decoder: decoder,emptyResponseCodes: emptyResponseCodes,emptyRequestMethods: emptyRequestMethods)}}#endifextension DataRequest {/// Adds a handler using a `DecodableResponseSerializer` to be called once the request has finished.////// - Parameters:/// - type: `Decodable` type to decode from response data./// - queue: The queue on which the completion handler is dispatched. `.main` by default./// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the/// `completionHandler`. `PassthroughPreprocessor()` by default./// - decoder: `DataDecoder` to use to decode the response. `JSONDecoder()` by default./// - encoding: The string encoding. Defaults to `nil`, in which case the encoding will be determined/// from the server response, falling back to the default HTTP character set, `ISO-8859-1`./// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default./// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default./// - completionHandler: A closure to be executed once the request has finished.////// - Returns: The request.@discardableResultpublic func responseDecodable<T: Decodable>(of type: T.Type = T.self,queue: DispatchQueue = .main,dataPreprocessor: DataPreprocessor = DecodableResponseSerializer<T>.defaultDataPreprocessor,decoder: DataDecoder = JSONDecoder(),emptyResponseCodes: Set<Int> = DecodableResponseSerializer<T>.defaultEmptyResponseCodes,emptyRequestMethods: Set<HTTPMethod> = DecodableResponseSerializer<T>.defaultEmptyRequestMethods,completionHandler: @escaping (AFDataResponse<T>) -> Void) -> Self {response(queue: queue,responseSerializer: DecodableResponseSerializer(dataPreprocessor: dataPreprocessor,decoder: decoder,emptyResponseCodes: emptyResponseCodes,emptyRequestMethods: emptyRequestMethods),completionHandler: completionHandler)}}extension DownloadRequest {/// Adds a handler using a `DecodableResponseSerializer` to be called once the request has finished.////// - Parameters:/// - type: `Decodable` type to decode from response data./// - queue: The queue on which the completion handler is dispatched. `.main` by default./// - dataPreprocessor: `DataPreprocessor` which processes the received `Data` before calling the/// `completionHandler`. `PassthroughPreprocessor()` by default./// - decoder: `DataDecoder` to use to decode the response. `JSONDecoder()` by default./// - encoding: The string encoding. Defaults to `nil`, in which case the encoding will be determined/// from the server response, falling back to the default HTTP character set, `ISO-8859-1`./// - emptyResponseCodes: HTTP status codes for which empty responses are always valid. `[204, 205]` by default./// - emptyRequestMethods: `HTTPMethod`s for which empty responses are always valid. `[.head]` by default./// - completionHandler: A closure to be executed once the request has finished.////// - Returns: The request.@discardableResultpublic func responseDecodable<T: Decodable>(of type: T.Type = T.self,queue: DispatchQueue = .main,dataPreprocessor: DataPreprocessor = DecodableResponseSerializer<T>.defaultDataPreprocessor,decoder: DataDecoder = JSONDecoder(),emptyResponseCodes: Set<Int> = DecodableResponseSerializer<T>.defaultEmptyResponseCodes,emptyRequestMethods: Set<HTTPMethod> = DecodableResponseSerializer<T>.defaultEmptyRequestMethods,completionHandler: @escaping (AFDownloadResponse<T>) -> Void) -> Self {response(queue: queue,responseSerializer: DecodableResponseSerializer(dataPreprocessor: dataPreprocessor,decoder: decoder,emptyResponseCodes: emptyResponseCodes,emptyRequestMethods: emptyRequestMethods),completionHandler: completionHandler)}}// MARK: - DataStreamRequest/// A type which can serialize incoming `Data`.public protocol DataStreamSerializer {/// Type produced from the serialized `Data`.associatedtype SerializedObject/// Serializes incoming `Data` into a `SerializedObject` value.////// - Parameter data: `Data` to be serialized.////// - Throws: Any error produced during serialization.func serialize(_ data: Data) throws -> SerializedObject}/// `DataStreamSerializer` which uses the provided `DataPreprocessor` and `DataDecoder` to serialize the incoming `Data`.public struct DecodableStreamSerializer<T: Decodable>: DataStreamSerializer {/// `DataDecoder` used to decode incoming `Data`.public let decoder: DataDecoder/// `DataPreprocessor` incoming `Data` is passed through before being passed to the `DataDecoder`.public let dataPreprocessor: DataPreprocessor/// Creates an instance with the provided `DataDecoder` and `DataPreprocessor`./// - Parameters:/// - decoder: ` DataDecoder` used to decode incoming `Data`. `JSONDecoder()` by default./// - dataPreprocessor: `DataPreprocessor` used to process incoming `Data` before it's passed through the/// `decoder`. `PassthroughPreprocessor()` by default.public init(decoder: DataDecoder = JSONDecoder(), dataPreprocessor: DataPreprocessor = PassthroughPreprocessor()) {self.decoder = decoderself.dataPreprocessor = dataPreprocessor}public func serialize(_ data: Data) throws -> T {let processedData = try dataPreprocessor.preprocess(data)do {return try decoder.decode(T.self, from: processedData)} catch {throw AFError.responseSerializationFailed(reason: .decodingFailed(error: error))}}}/// `DataStreamSerializer` which performs no serialization on incoming `Data`.public struct PassthroughStreamSerializer: DataStreamSerializer {/// Creates an instance.public init() {}public func serialize(_ data: Data) throws -> Data { data }}/// `DataStreamSerializer` which serializes incoming stream `Data` into `UTF8`-decoded `String` values.public struct StringStreamSerializer: DataStreamSerializer {/// Creates an instance.public init() {}public func serialize(_ data: Data) throws -> String {String(decoding: data, as: UTF8.self)}}#if swift(>=5.5)extension DataStreamSerializer {/// Creates a `DecodableStreamSerializer` instance with the provided `DataDecoder` and `DataPreprocessor`.////// - Parameters:/// - type: `Decodable` type to decode from stream data./// - decoder: ` DataDecoder` used to decode incoming `Data`. `JSONDecoder()` by default./// - dataPreprocessor: `DataPreprocessor` used to process incoming `Data` before it's passed through the/// `decoder`. `PassthroughPreprocessor()` by default.public static func decodable<T: Decodable>(of type: T.Type,decoder: DataDecoder = JSONDecoder(),dataPreprocessor: DataPreprocessor = PassthroughPreprocessor()) -> Self where Self == DecodableStreamSerializer<T> {DecodableStreamSerializer<T>(decoder: decoder, dataPreprocessor: dataPreprocessor)}}extension DataStreamSerializer where Self == PassthroughStreamSerializer {/// Provides a `PassthroughStreamSerializer` instance.public static var passthrough: PassthroughStreamSerializer { PassthroughStreamSerializer() }}extension DataStreamSerializer where Self == StringStreamSerializer {/// Provides a `StringStreamSerializer` instance.public static var string: StringStreamSerializer { StringStreamSerializer() }}#endifextension DataStreamRequest {/// Adds a `StreamHandler` which performs no parsing on incoming `Data`.////// - Parameters:/// - queue: `DispatchQueue` on which to perform `StreamHandler` closure./// - stream: `StreamHandler` closure called as `Data` is received. May be called multiple times.////// - Returns: The `DataStreamRequest`.@discardableResultpublic func responseStream(on queue: DispatchQueue = .main, stream: @escaping Handler<Data, Never>) -> Self {let parser = { [unowned self] (data: Data) inqueue.async {self.capturingError {try stream(.init(event: .stream(.success(data)), token: .init(self)))}self.updateAndCompleteIfPossible()}}$streamMutableState.write { $0.streams.append(parser) }appendStreamCompletion(on: queue, stream: stream)return self}/// Adds a `StreamHandler` which uses the provided `DataStreamSerializer` to process incoming `Data`.////// - Parameters:/// - serializer: `DataStreamSerializer` used to process incoming `Data`. Its work is done on the `serializationQueue`./// - queue: `DispatchQueue` on which to perform `StreamHandler` closure./// - stream: `StreamHandler` closure called as `Data` is received. May be called multiple times.////// - Returns: The `DataStreamRequest`.@discardableResultpublic func responseStream<Serializer: DataStreamSerializer>(using serializer: Serializer,on queue: DispatchQueue = .main,stream: @escaping Handler<Serializer.SerializedObject, AFError>) -> Self {let parser = { [unowned self] (data: Data) inself.serializationQueue.async {// Start work on serialization queue.let result = Result { try serializer.serialize(data) }.mapError { $0.asAFError(or: .responseSerializationFailed(reason: .customSerializationFailed(error: $0))) }// End work on serialization queue.self.underlyingQueue.async {self.eventMonitor?.request(self, didParseStream: result)if result.isFailure, self.automaticallyCancelOnStreamError {self.cancel()}queue.async {self.capturingError {try stream(.init(event: .stream(result), token: .init(self)))}self.updateAndCompleteIfPossible()}}}}$streamMutableState.write { $0.streams.append(parser) }appendStreamCompletion(on: queue, stream: stream)return self}/// Adds a `StreamHandler` which parses incoming `Data` as a UTF8 `String`.////// - Parameters:/// - queue: `DispatchQueue` on which to perform `StreamHandler` closure./// - stream: `StreamHandler` closure called as `Data` is received. May be called multiple times.////// - Returns: The `DataStreamRequest`.@discardableResultpublic func responseStreamString(on queue: DispatchQueue = .main,stream: @escaping Handler<String, Never>) -> Self {let parser = { [unowned self] (data: Data) inself.serializationQueue.async {// Start work on serialization queue.let string = String(decoding: data, as: UTF8.self)// End work on serialization queue.self.underlyingQueue.async {self.eventMonitor?.request(self, didParseStream: .success(string))queue.async {self.capturingError {try stream(.init(event: .stream(.success(string)), token: .init(self)))}self.updateAndCompleteIfPossible()}}}}$streamMutableState.write { $0.streams.append(parser) }appendStreamCompletion(on: queue, stream: stream)return self}private func updateAndCompleteIfPossible() {$streamMutableState.write { state instate.numberOfExecutingStreams -= 1guard state.numberOfExecutingStreams == 0, !state.enqueuedCompletionEvents.isEmpty else { return }let completionEvents = state.enqueuedCompletionEventsself.underlyingQueue.async { completionEvents.forEach { $0() } }state.enqueuedCompletionEvents.removeAll()}}/// Adds a `StreamHandler` which parses incoming `Data` using the provided `DataDecoder`.////// - Parameters:/// - type: `Decodable` type to parse incoming `Data` into./// - queue: `DispatchQueue` on which to perform `StreamHandler` closure./// - decoder: `DataDecoder` used to decode the incoming `Data`./// - preprocessor: `DataPreprocessor` used to process the incoming `Data` before it's passed to the `decoder`./// - stream: `StreamHandler` closure called as `Data` is received. May be called multiple times.////// - Returns: The `DataStreamRequest`.@discardableResultpublic func responseStreamDecodable<T: Decodable>(of type: T.Type = T.self,on queue: DispatchQueue = .main,using decoder: DataDecoder = JSONDecoder(),preprocessor: DataPreprocessor = PassthroughPreprocessor(),stream: @escaping Handler<T, AFError>) -> Self {responseStream(using: DecodableStreamSerializer<T>(decoder: decoder, dataPreprocessor: preprocessor),stream: stream)}}