web-dev-qa-db-fra.com

Comment faire pour que NSJSONSerialization génère un booléen true ou false?

J'utilise NSJSONSerialization dataWithJSONObject pour sérialiser mes classes en JSON. Lorsqu'il sérialise un BOOL, il lui donne la valeur 1 ou 0 dans la chaîne JSON. J'ai besoin que cela soit vrai ou faux à la place. Est-ce possible de le faire génériquement?

25
Triton Man

Non, l'objet de base d'un booléen est NSNumbernumberWithBool, qui devient 0 ou 1. Nous n'avons aucun objet Bool. Idem pour lire JSON. Vrai/faux deviendra à nouveau une NSNumber.

Vous pouvez créer une classe Bool et créer votre propre analyseur. Les tableaux sont des tableaux et les objets JSON sont NSDictionary. Vous pouvez interroger les clés, tester la classe derrière et construire la chaîne JSON à partir de celle-ci.

3
Helge Becker

Lorsque je crée [NSNumber numberWithBool:NO], NSJSONSerialization renvoie le mot "false" dans la chaîne JSON.

EDITAvec les nouveaux raccourcis, vous pouvez également utiliser ces types pratiques:

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

De cette façon, vous pouvez éviter quelque chose comme une boucle entre vos valeurs. Je veux le comportement opposé exact mais avoir des objets NSNumber. Donc je dois faire une boucle ...

EDIT II

mbi a souligné dans les commentaires qu'il y avait une différence entre les versions d'iOS. Alors voici un test 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}
24
Julian F. Weinert

Je suis juste tombé dessus moi-même, pas sûr que ce soit la meilleure réponse mais ...

Assurez-vous d’utiliser @YES ou @NO, votre json généré aura alors vrai/faux:

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

Vous devrez donc transformer vos autres "booléens"/booléens en valeurs -> @YES/@NO lors de la mise dans le dictionnaire de dataWithJSONObject.

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

Oui, il est possible de générer un booléen (vrai/faux) avec NSJSONSerialization en utilisant kCFBooleanTrue et kCFBooleanFalse :

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

puis

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

Je viens de frapper la question sur iOS9. Mon cas est que j'ai une propriété CoreData workout.private qui est mappée sur NSNumber * en raison de la gestion de CoreData.

Lors de la création de JSON, [NSNumber numberWithBool:workout.private.boolValue] définit les valeurs true/false attendues dans JSON, mais workout.private ou @ (workout.private.boolValue) définit également "1" ou "0".

1
mixtly87

J'ai rencontré un problème similaire lors de l'utilisation du booléen de CoreData, qui est également stocké sous le numéro NSNumber. La solution la plus simple pour moi consistait à utiliser @ ():

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

J'imagine que @ () reconnaît la valeur BOOL et initialise le NSNumber avec numberWithBool: ce qui conduit à true/false en JSON

0
JakubKnejzlik