4

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
    }
}
gcharita
  • 7,729
  • 3
  • 20
  • 37
Hexycode
  • 428
  • 8
  • 26

1 Answers1

3

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)
}
gcharita
  • 7,729
  • 3
  • 20
  • 37
  • thanks for help! You solution works to solve that error. Is it possible to have a small chat with you regarding alamofire 5? – Hexycode Sep 25 '20 at 07:53
  • @Hexycode Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/222062/between-gcharita-and-hexycode). – gcharita Sep 25 '20 at 08:10