Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AFNetworking JSON request with a boolean

I'm trying to send a JSON request using AFNetworking and have a problem with making values be translated to the json form of {"value": true}. Instead, I'm getting: {"value": 1}

Here's basically how I'm creating the request:

NSMutableURLRequest *request =
    [self.httpClient requestWithMethod:@"POST"
                                  path:url
                            parameters:@{@"value": @YES}];

AFJSONRequestOperation *operation =
    [AFJSONRequestOperation JSONRequestOperationWithRequest:request ...];
    [operation start];

Am I missing something trivial here? :)

like image 806
abyx Avatar asked Dec 24 '12 16:12

abyx


3 Answers

Short answer: Make sure you are running a recent version of AFNetworking. That's all I can see as the problem based on the code you've provided.

Long answer: I've tried reproducing the issue you're describing with the most recent versions of AFNetworking and I could not. I dug into AFNetworking to see how the encoding of JSON is done. AFHTTPClient.m:442 uses NSJSONSerialization to encode JSON requests. I came up with the following code to test the issue:

NSError* error = nil;
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:@{@"value" : @YES} options:0 error:&error];
NSLog(@"Resulting JSON:\n\n%@\n", [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]);

outputs:

{"value":true}

So @YES should do it. As a note, be sure not to use @(YES) in your code as it will output as a 1 instead of true.

NSError* error = nil;
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:@{@"value" : @(YES)} options:0 error:&error];
NSLog(@"JSON:%@", [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]);

outputs:

{"value":1}

With that I went through and tried to figure out how AFHTTPClient need to be configured to send out a bool as 1/0 instead of true/false and could not find any. Here's my networking code.

AFHTTPClient* httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:@"http://<SERVER HERE>"]];
[httpClient setParameterEncoding:AFJSONParameterEncoding];
NSMutableURLRequest *jsonRequest = [httpClient requestWithMethod:@"POST" path:@"/" parameters:@{@"value": @YES}];

AFHTTPRequestOperation *jsonOperation = [AFJSONRequestOperation JSONRequestOperationWithRequest:jsonRequest success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
    NSLog(@"Success");
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
    NSLog(@"Failure");
}];
[jsonOperation start];
like image 90
Pierre-Luc Simard Avatar answered Nov 02 '22 23:11

Pierre-Luc Simard


Since @YES is an NSNumber, NSJSONSerialization turns this to 0/1.

I don't think there's a way other than @{@"value": (yesOrNo ? @"true" : @"false")} or using a different serialization class.

like image 42
Tal Bereznitskey Avatar answered Nov 03 '22 00:11

Tal Bereznitskey


For people who might be running into this issue, there's another reason why it might be happening.

Make sure you set the parameterEncoding property of your AFHTTPClient subclass to AFJSONParameterEncoding, otherwise you'll run into the issue of NSNumber's initialization value not being correctly detected, and will see 0s and 1s being output instead by the encoder.

See this for reference as well.

Hope this helps.

like image 1
Alexandr Kurilin Avatar answered Nov 02 '22 22:11

Alexandr Kurilin