如何使用NSJSONSerialization将布尔值输出为true或false?

28

我正在使用NSJSONSerialization dataWithJSONObject将我的类序列化为JSON。当它序列化BOOL时,在JSON字符串中它会赋值为1或0。我需要它代表true或false,这是否可以通用地实现?

6个回答

30

当我创建[NSNumber numberWithBool:NO]时,NSJSONSerialization会在JSON字符串中返回单词"false"。

编辑使用新的快捷方式,您也可以使用这些方便的工具:

@(YES) /   @(NO)
@(1)   /   @(0)
@YES   /   @NO
@1     /   @0

通过这种方式,您可以避免像循环遍历值之类的操作。但我想要完全相反的行为,而又有NSNumber对象。所以我必须循环处理...

编辑 II

mbi 在评论中指出 iOS 版本之间存在差异。因此,这里是一个 iOS9 测试:

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}

5
这里在iOS版本之间有一个小细节需要注意!这段代码: [NSJSONSerialization dataWithJSONObject:@{ @"Test1" : @YES, @"Test2" : @(YES), @"Test3" : @true, @"Test4" : @(true) } options:nil error:nil] 在iOS 9上产生的JSON如下: {"Test4":true,"Test3":true,"Test2":true,"Test1":true} 但在iOS 8及以下版本上,它会产生以下JSON: {"Test4":1,"Test3":1,"Test2":true,"Test1":true} - mbi
有趣… 感谢这个发现! - Julian F. Weinert
不好意思,我没有看到那个。我会删除我的评论。谢谢你指出来! - Helge Becker

15

刚刚自己遇到了这个问题,不确定这是否是最佳答案,但请注意使用@YES或@NO,然后您的输出json将会包含true/false:

[NSJSONSerialization dataWithJSONObject:@{@"test": @YES} options:0 error: nil];

在使用dataWithJSONObject方法将数据存入字典时,您需要将其他“布尔值”或类似于布尔值的值转换为@YES / @NO。

[NSJSONSerialization dataWithJSONObject:@{@"test": (boolLikeValue ? @YES : @NO)} options:0 error: nil];

我觉得这个很有帮助,因为并不总是能直接使用字面量。例如,在一个接收BOOL参数的函数中,你需要将原始的BOOL转换为可识别的@BOOL字面量之一,如@YES@NO - Motti Shneor

5

使用kCFBooleanTruekCFBooleanFalse,NSJSONSerialization可以输出布尔值(true / false):

NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:kCFBooleanTrue, @"key_1",
                           kCFBooleanFalse, @"key_2",
                           nil]  

那么

NSError *error = nil;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:kNilOptions error:&error];

3
不,布尔类型的基础对象是NSNumbernumberWithBool方法,其结果为0或1。我们没有Bool对象。同样,在读取JSON时,true和false也会再次变成NSNumber类型。
你可以创建一个Bool类并构建自己的解析器。数组仍然是数组,JSON对象是NSDictionary类型。您可以查询键、测试该键对应的类型,并从中构建JSON字符串。

2
谢谢,我创建了自己的JSONBool类,并成功地让它工作。 - Rocky Pulley
@TritonMan能否在JSONBool类中再发布更多的代码?我也想实现同样的功能。 - TahoeWolverine
是的,NSJSONSerialization的工作方式随着时间的推移而发生了变化。请注意此问题被提出和回答的日期。 - Helge Becker
@Julian在下面使用[NSNumber numberWithBool:NO]的答案现在更简单易懂。 - Jan

1

当我使用CoreData的布尔值时,遇到了类似的问题,它也被存储为NSNumber。对我来说最简单的解决方案是使用@():

[NSJSONSerialization dataWithJSONObject:@{@"bool": @([object.value boolValue])} options:0 error: nil];

我猜@()会识别BOOL值并使用numberWithBool:初始化NSNumber,这导致JSON中的true/false。

1
我刚在iOS9上遇到了问题。 我的情况是,我有一个CoreData属性workout.private,它是bool类型,由于CoreData的处理,被映射为NSNumber*。
创建JSON时,[NSNumber numberWithBool:workout.private.boolValue]会在JSON中设置预期的true/false,但只有workout.private或@(workout.private.boolValue)会设置"1"或"0"。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接