How to remove square brackets from Alamofire array values

Alamofire will add square brackets for the key of array values. This article will show you how to remove those brackets.

By default, array values will be encoded to parameters like this.

foo[]=bar1&foo[]=bar2

This time we will make no square brackets parameters with ParameterEncoding.

foo=bar1&foo=bar2

Examples with ParameterEncoding

Alamofire allow to change encoding formats with ParameterEncoding.

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)

Why collection types have multiple implementation ways

Current RFC does not define clear ways for how to encode collection types. Alamofire’s README mentioned it.

Since there is no published specification for how to encode collection types, Alamofire follows the convention of appending [] to the key for array values (foo[]=1&foo[]=2), and appending the key surrounded by square brackets for nested dictionary values (foo[bar]=baz).

References

https://github.com/Alamofire/Alamofire/issues/965

Hiroki Matsue

Read more posts by this author.

Tokyo, Japan https://256days.com/