Search code examples
swiftalamofireswift3swifty-json

Cannot call value of non-function type 'HTTPURLResponse?' - Alamofire 4.0


I just started converting my old project from swift 2.2->3.0. In this process I had to update Alamofire to version 4.0 to get support for the new swift version. I've fixed the most but this I'm coming up short with?

Can anyone explain why the last return statement shows the following error:

Cannot call value of non-function type 'HTTPURLResponse?'

Specifically:

return response(responseSerializer: responseSerializer, completionHandler: completionHandler)

extension Alamofire.DataRequest {
func responseTVArray(_ completionHandler: @escaping (DataResponse<TVWrapper>, Error?) -> Void) -> Self {
    let responseSerializer = DataResponseSerializer<TVWrapper> { request, response, data, error in
        guard error == nil else { return .failure(error!) }

        guard let responseData = data else
        {
            let failureReason = "Array could not be serialized because input data was nil."

            let userInfo = [NSLocalizedFailureReasonErrorKey: failureReason]
            let error = NSError(domain: "UMAT", code: ErrorCode.DataSerializationFailed.rawValue, userInfo: userInfo)

            return .failure(error)
        }

        let JSONResponseSerializer = DataRequest.jsonResponseSerializer(options: .allowFragments)
        let result = JSONResponseSerializer.serializeResponse(request, response, responseData, error)

        switch result {
        case .success(let value):
            let json = SwiftyJSON3.JSON(value)
            let wrapper = TVWrapper()
            wrapper.page = json["page"].intValue
            wrapper.totalPages = json["total_pages"].intValue
            wrapper.totalResults = json["total_results"].intValue

            var allTV:Array = Array<TV>()

            let results = json["results"]

            for jsonTV in results
            {
                let tv = TV(json: jsonTV.1, id: Int(jsonTV.0) )
                if (tv.posterPath == "")
                {
                    continue
                }
                else
                {
                    allTV.append(tv)
                }

            }
            wrapper.results = allTV
            return .success(wrapper)
        case .failure(let error):
            return .failure(error)
        }
    }

    return response(responseSerializer: responseSerializer, completionHandler: completionHandler)
}

Solution

  • @Mat0 Thanks for your comment. I'm writing this answer because I have couple more spots to fix in my case.

    The below is the method I had in Swift 2.2.

    func responseSLJSON(completionHandler: Response<AnyObject, NSError> -> Void,
                                 errorHandler: (String, Result<AnyObject, NSError>) -> NSError = Request.slError()) -> Self {
    
        let responseSerializer = ResponseSerializer<AnyObject, NSError> {
            request, response, data, error in
    
            let JSONSerializer = Request.JSONResponseSerializer(options: .AllowFragments)
    
            guard error == nil else {
                let errorResult = JSONSerializer.serializeResponse(request, response, data, nil)
                return .Failure(errorHandler(#function, errorResult))
            }
    
            return JSONSerializer.serializeResponse(request, response, data, error)
        }
    
        return response(responseSerializer: responseSerializer, completionHandler: completionHandler)
    }
    

    And I converted this like...

    func responseSLJSON(completionHandler: @escaping (DataResponse<Any>) -> Void,
                        errorHandler: @escaping (String, Result<Any>) -> NSError = DataRequest.slError()) -> Self {
    
        let responseSerializer = DataResponseSerializer<Any> {
            request, response, data, error in
    
            let jsonSerializer = DataRequest.jsonResponseSerializer(options: .allowFragments)
    
            guard error == nil else {
                let errorResult = jsonSerializer.serializeResponse(request, response, data, nil)
                return .failure(errorHandler(#function, errorResult))
            }
    
            return jsonSerializer.serializeResponse(request, response, data, error)
        }
    
        return response(responseSerializer: responseSerializer, completionHandler: completionHandler)
    }
    

    The return response(responseSerializer: responseSerializer, completionHandler: completionHandler) was about parameter type in this case. I had to use Any instead of AnyObject because jsonResponseSerializer returns DataResponseSerializer<Any>.

    public static func jsonResponseSerializer(
        options: JSONSerialization.ReadingOptions = .allowFragments)
        -> DataResponseSerializer<Any>
    

    Also @escaping was essential for completionHandler parameter.