Invoking the request method with a [String, AnyObject] dictionary passed as argument yields query parameters where Bools are encoded as 0s and 1s. I would like them to be encoded as true and false respectively. The parameter encoding in this request was .URL.
Alamofire.request(endpoint.method(), url, parameters: parameters, encoding: encoding, headers: headers)
.validate(statusCode: 200...299)
.responseJSON { response in self.handleRequestResponse(response, observer: observer) }
I'm using Swift 2 in XCode 7.2.1 with a mixed codebase.
This isn't true. What happens is the Bool bridges to an NSNumber when converted to an AnyObject. When you print out an NSNumber created from a Bool, it prints out 0 or 1. However, once you run it through NSJSONSerialization, it encodes it as either false or true.
Cheers. 🍻
But you wouldn't run URL query parameters through NSJSONSerialization would you?
Anyways, I'm monitoring the traffic with TCPMon and it shows the URLs with Bools encoded as 0s and 1s. Right now I'm working around this by converting Bool values to Strings before making the request. Maybe this is intended behavior, if so let me know.
Cheers
Oh my apologies, I missed the .URL encoding parameter type. I'm going to re-open this and investigate further.
No worries, thanks for looking into this!
Okay @pheuberger, I managed to dig into this a bit more. The behavior you are seeing is intended. The reason has to do with the fact that all the parameters bridge over to Objective-C. The parameter encoding logic for URL encoding relies on the CustomStringConvertible protocol to covert the AnyObject to a string representation. In the case of an NSNumber, this will always default to 0 or 1 in the case of a Bool.
let boolValue = true
print(boolValue) // outputs `true`
let bridgedBool: AnyObject = true
print(bridgedBool) // outputs `1`
In order for us to change this to true or false, we'd have to implement some fairly complicated and fragile logic into the ParameterEncoding enum that I'm not comfortable doing. Additionally, this is the behavior that all other users currently expect, so it wouldn't be a backwards compatible change in any way. For now, I'd recommend you continue using your current solution to turn the Bool values into Strings before encoding.
Once Swift 3 is released, we'll re-investigate as to whether parameters should come in as [String: AnyObject] dictionaries or [String: Any] dictionaries allowing everything to stay 100% swift.
Cheers. 🍻
Alright, I understand the reasoning behind it and it seems reasonable from your point of view. I converted the values to string now anyway, so it's not a big problem for me. Again thanks for looking into it and I'll look forward to Swift 3! :smiley:
Hey guys,
I'm looking at the queryComponents method in ParameterEncoding and I can see that "1" and "0" is deliberately set as a representation of a bool value in a URL. In Swift 3/Alamofire 4, it is still the case. Why is that? Why is it not "true" and "false"? I feel that I'm missing something here but I don't know what.
I can also see that you guys changed the input value type to Any so a "pure" Swift bool can be passed in. I tried printing 'true' and it printed "true".
@AppsTitude The unfortunate fact of the matter is that there is no single standard for encoding parameters in a URL query. Some of the standards that do exist (largely server implementations) vary between true/false and 1/0. Also, when implementing the new workaround for Swift 3, we matched our old behavior that used 1/0 so as not to break backward compatibility.
@jshier That is unfortunate indeed… Where are the rfc guys when we need them!
But how to solve? I can't pass "true" or "false" as a string since server side is expecting a bool, not string.
I am facing this same issue. Any update on the same ?
use JSONEncoding.default encoding when you create the Alamofire request.
There are cases where we want to use JSON encoding in a query string / url query. It doesn't seem to be possible to accomplish bools sent as "true" and "false" in a URL query string (suitable for get method).
Not with the quotes, no, but with 4.7, you can choose between 0/1 and false/true. If you need both URL parameters and body JSON, you can easily create your own ParameterEncoding or manually encode your requests.
@jshier how to choose false/true encoding?
@richardtop you need to set the boolEncoding: .literal in the URLEncoding initializer.
Most helpful comment
@richardtop you need to set the
boolEncoding: .literalin theURLEncodinginitializer.