Was reviewing my colleague code and this error appears.
Any ideas what's wrong with it? Was trying to Run the build and unfortunately this error appears
Error -> Trailing closure passed to parameter of type 'Set<HTTPMethod>' that does not accept a closure
Was trying to change it on DataResponseSerializer<T>
doesn't work out for me
Error line -> let responseSerializer = DataResponseSerializer { (request, response, data, error) in
Code here
import Foundation
import Alamofire
extension DataRequest {
/// @Returns - DataRequest
/// completionHandler handles JSON Object T
/// - Returns: `DataRequest`
@discardableResult func responseObject<T: Decodable> (
queue: DispatchQueue? = nil,
_ type: T.Type,
completionHandler: @escaping (AFDataResponse<T>) -> Void
) -> Self {
let responseSerializer = DataResponseSerializer { (_, response, data, error) in
if let err = error {
return .failure(err)
}
let result = DataRequest.serializeResponseData(response: response, data: data, error: error)
let jsonData: Data
switch result {
case .failure(let error):
return .failure(error)
case .success(let data):
jsonData = data
}
// (1)- Json Decoder. Decodes the data object into expected type T
// throws error when failes
let decoder = JSONCoders.snakeCaseDecoder
do {
let decoded = try decoder.decode(T.self, from: jsonData)
return .success(decoded)
} catch let error {
return .failure(error)
}
}
return response(queue: queue, responseSerializer: responseSerializer, completionHandler: completionHandler)
}
}
EDIT1:
Error still appears it pointing me out specifically on this bracket - DataResponseSerializer {
that something wrong with it. I already try to delete them/add new ones. No idea what's the problem here. I cannot run build cause of this error currently.
This is definition of DataResponseSerializer
/// 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 response is has a status code valid for
/// empty responses (`204`, `205`), then an empty `Data` value is returned.
public final class DataResponseSerializer: ResponseSerializer {
public let dataPreprocessor: DataPreprocessor
public let emptyResponseCodes: Set<Int>
public let emptyRequestMethods: Set<HTTPMethod>
/// Creates an instance using 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.
public init(dataPreprocessor: DataPreprocessor = DataResponseSerializer.defaultDataPreprocessor,
emptyResponseCodes: Set<Int> = DataResponseSerializer.defaultEmptyResponseCodes,
emptyRequestMethods: Set<HTTPMethod> = DataResponseSerializer.defaultEmptyRequestMethods) {
self.dataPreprocessor = dataPreprocessor
self.emptyResponseCodes = emptyResponseCodes
self.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
}
}
Alamofire version 5, that you are probably using now, has some breaking changes with the previous versions. The initializer of DataResponseSerializer
is no longer getting a closure parameter like Alamofire 4.
However, you can achieve what are you trying much easier, since Alamofire 5 has already a responseDecodable(of:queue:decoder:completionHandler:)
function, in which you can pass in your custom JSONDecoder
and make the decoding process for you:
extension DataRequest {
/// @Returns - DataRequest
/// completionHandler handles JSON Object T
/// - Returns: `DataRequest`
@discardableResult func responseObject<T: Decodable> (
queue: DispatchQueue? = nil,
_ type: T.Type,
completionHandler: @escaping (AFDataResponse<T>) -> Void
) -> Self {
let decoder = JSONCoders.snakeCaseDecoder
return responseDecodable(
of: T.self,
queue: queue ?? .main,
decoder: decoder,
completionHandler: completionHandler
)
}
}
You can even do that without a DataRequest
extension directly when you make the request. If let's say you are using a generic function for all your requests, your code might look like this:
func myGenericRequest<T: Decodable>(url: URL, completionHandler: @escaping (DataResponse<T, AFError>) -> Void) {
let decoder = JSONCoders.snakeCaseDecoder
AF.request(url).responseDecodable(decoder: decoder, completionHandler: completionHandler)
}