Fahim Parkar
Fahim Parkar

Reputation: 31647

alamofire is not preparing correct url

I am using alamofire for calling webservice.

request(url, method: webMethod, parameters: webParams, encoding: URLEncoding.default, headers: headers)
        .validate(statusCode: 200..<300)
        .responseJSON { (response) in
            print("responseresponse===\(response.request)")

I am getting below log for the same.

responseresponse===http://www.mywebsite.com/api/searchFlight?
    adults=3&charter=true&directFlight=true&
    flexibleDays=0&flightClass=PREMIUM_ECONOMY&
    offerLimit=10&refundableOnly=false&
    routes%5B%5D=KWI-BOM%2C2018-08-09&routes%5B%5D=BOM-KWI%2C2018-08-25

Params I am passing as below & they are of type [String: Any]

[
    "adults": 3, 
    "directFlight": "true", 
    "flightClass": "PREMIUM_ECONOMY", 
    "refundableOnly": "false", 
    "offerLimit": 10, 
    "flexibleDays": "0", 
    "charter": "true", 
    "routes": ["KWI-BOM,2018-08-09", "BOM-KWI,2018-08-25"]
]

This return me status code as 400 which means Invalid request.

I don't understand why routes are giving wrong output? Routes are coming as below

routes%5B%5D=KWI-BOM%2C2018-08-09&routes%5B%5D=BOM-KWI%2C2018-08-25
      ^^^^^^                            ^^^^^^

I was expecting routes to be as below.

routes=KWI-BOM%2C2018-08-09&routes=BOM-KWI%2C2018-08-25

I idea what I am missing?

Upvotes: 1

Views: 1204

Answers (3)

Fahim Parkar
Fahim Parkar

Reputation: 31647

Below is what I did

Swift3

Remove square brackets for GET request

struct CustomGetEncoding: ParameterEncoding {
    func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
        var request = try URLEncoding().encode(urlRequest, with: parameters)
        request.url = URL(string: request.url!.absoluteString.replacingOccurrences(of: "%5B%5D=", with: "="))
        return request
    }
}

...

Alamofire.request("http://example.com", method: .get, parameters: ["foo": ["bar1", "bar2"]], encoding: CustomGetEncoding())

Remove square brackets for POST request

struct CustomPostEncoding: ParameterEncoding {
    func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
        var request = try URLEncoding().encode(urlRequest, with: parameters)
        let httpBody = NSString(data: request.httpBody!, encoding: String.Encoding.utf8.rawValue)!
        request.httpBody = httpBody.replacingOccurrences(of: "%5B%5D=", with: "=").data(using: .utf8)
        return request
    }
}

...

Alamofire.request("http://example.com", method: .post, parameters: ["foo": ["bar1", "bar2"]], encoding: CustomPostEncoding())

Swift2

Remove square brackets for GET request

let parameterEncoding = ParameterEncoding.Custom { requestConvertible, parameters in
    let (mutableRequest, error) = ParameterEncoding.URL.encode(requestConvertible, parameters: parameters)
    mutableRequest.URL = NSURL(string: mutableRequest.URLString.stringByReplacingOccurrencesOfString("%5B%5D=", withString: "="))
    return (mutableRequest, error)
}

Alamofire.request(.GET, "http://example.com", parameters: ["foo": ["bar1", "bar2"]], encoding: parameterEncoding)

Remove square brackets for POST request

let parameterEncoding = ParameterEncoding.Custom { requestConvertible, parameters in
    let (mutableRequest, error) = ParameterEncoding.URL.encode(requestConvertible, parameters: parameters)
    let httpBody = NSString(data: mutableRequest.HTTPBody!, encoding: NSUTF8StringEncoding)!
    mutableRequest.HTTPBody = httpBody.stringByReplacingOccurrencesOfString("%5B%5D=", withString: "=").dataUsingEncoding(NSUTF8StringEncoding)
    return (mutableRequest, error)
}

Alamofire.request(.POST, "http://example.com", parameters: ["foo": ["bar1", "bar2"]], encoding: parameterEncoding)

Reference

Upvotes: 2

Dan
Dan

Reputation: 749

%5B%5D is UrlQueryAllowed encoded []. That's Alamofire striking again - it sees that routes param is a dictionary so it passes routes[]=foo&routes[]=bar instead of routes=foo&routes=bar and your backend complains about wrong parameter (routes is mandatory?). Not quite sure why Alamofire does this and if HTTP needs an array parameters to have [] at the end of their key - never had to pass an array as a query param. I'd simply try encoding the routes by hand and passing routes: <String> with some delimiter.

Or change my backend to expect routes[] instead of routes. That seems the easier fix.

Upvotes: 0

Martin Ruiz
Martin Ruiz

Reputation: 21

I suppose that the webmethod is equals to .post and trying to change enconding: JSONEncoding.default, in that case the request do not send the data through the url but from the body data. That is because complex data can not be sent through the url. Also try to verify that your end-point recieve an object with the same property names and that the types match. I've performed several post request with Alamofire and they worked as expected.

Upvotes: -1

Related Questions