I'm using NSJSONSerialization dataWithJSONObject to serialize my classes to JSON. When it serializes a BOOL, it gives it the value 1 or 0 in the JSON string. I need this to be true or false instead. Is this possible to do generically?
No, the Foundation Object for a Bool is NSNumber
numberWithBool
, which becomes either 0 or 1. We have no Bool
Object. Same go for reading JSON
. True/false will become a NSNumber
again.
You could create an Bool
Class and build your own parser. Arrays are Arrays and JSON
Objects are NSDictionary
. You can query the keys, test what Class lies behind and build the JSON
String from this.
[NSNumber numberWithBool:NO]
is much simpler nowadays –
Ultima When I create [NSNumber numberWithBool:NO]
, the NSJSONSerialization returns the word "false" in the JSON string.
EDIT With the new shortcuts you can also use these handy guys:
@(YES) / @(NO)
@(1) / @(0)
@YES / @NO
@1 / @0
This way you can avoid something like looping through your values. I want the exact opposite behavior but have NSNumber
objects. So I have to loop...
EDIT II
mbi pointed out in the comments that there is a difference between iOS versions. So here is an iOS9 test:
NSDictionary *data = @{
@"a": @(YES),
@"b": @YES,
@"c": @(1),
@"d": @1
};
NSLog(@"%@", [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:data options:0 error:nil] encoding:NSUTF8StringEncoding]);
2016-07-05 02:23:43.964 Test App[24581:6231996] {"a":true,"b":true,"c":1,"d":1}
[NSJSONSerialization dataWithJSONObject:@{ @"Test1" : @YES, @"Test2" : @(YES), @"Test3" : @true, @"Test4" : @(true) } options:nil error:nil]
produces this json on iOS 9 {"Test4":true,"Test3":true,"Test2":true,"Test1":true}
but produces this json on iOS 8 and below {"Test4":1,"Test3":1,"Test2":true,"Test1":true}
–
Revocation Just ran across this myself, not sure if this is the best answer but...
Make sure to use @YES or @NO, then your outputted json will have true / false in it:
[NSJSONSerialization dataWithJSONObject:@{@"test": @YES} options:0 error: nil];
So you will have to turn your other "booleans" / boolean like values -> @YES / @NO when putting into the dictionary for dataWithJSONObject.
[NSJSONSerialization dataWithJSONObject:@{@"test": (boolLikeValue ? @YES : @NO)} options:0 error: nil];
BOOL
parameter, you'll need to convert the primitive BOOL
to one of the acknowledgeable @BOOL
literals` @YES` and @NO
–
Squamation Yes, it is possible to output a boolean (true/false) with NSJSONSerialization by using kCFBooleanTrue and kCFBooleanFalse :
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:kCFBooleanTrue, @"key_1",
kCFBooleanFalse, @"key_2",
nil]
then
NSError *error = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:kNilOptions error:&error];
No, the Foundation Object for a Bool is NSNumber
numberWithBool
, which becomes either 0 or 1. We have no Bool
Object. Same go for reading JSON
. True/false will become a NSNumber
again.
You could create an Bool
Class and build your own parser. Arrays are Arrays and JSON
Objects are NSDictionary
. You can query the keys, test what Class lies behind and build the JSON
String from this.
[NSNumber numberWithBool:NO]
is much simpler nowadays –
Ultima I ran into similar issue when using CoreData's boolean, which is stored as NSNumber too. The easiest solution for me was using @():
[NSJSONSerialization dataWithJSONObject:@{@"bool": @([object.value boolValue])} options:0 error: nil];
I guess @() does recognize the BOOL value and initialize the NSNumber with numberWithBool: which leads to true/false in JSON
I just hit the issue on iOS9.
My case is that I have a CoreData property workout.private
which is bool mapped to NSNumber* due to CoreData handling.
When creating JSON
[NSNumber numberWithBool:workout.private.boolValue]
sets expected true/false in JSON, but just workout.private
or @(workout.private.boolValue) sets "1" or "0".
© 2022 - 2024 — McMap. All rights reserved.