web-dev-qa-db-fra.com

Que font les options de JSONSerialization et comment changent-elles jsonResult?

J'utilise JSONSerialization assez souvent dans mon projet. Voici un exemple de mon code JSONSerialization:

let json = try JSONSerialization.jsonObject(with: data!, options: []) as? [String: Any] 

Remarque : Des options manquent à des fins et je les ai normalement dans mon projet.

Mon problème est que je ne sais pas trop quoi faire ces options: [] faire?

Ce que j'ai trouvé sur les options:

NSJSONReadingMutableContainers:

Spécifie que les tableaux et les dictionnaires sont créés en tant qu'objets mutables.

NSJSONReadingMutableLeaves:

Spécifie que les chaînes de feuilles du graphique d'objet JSON sont créées en tant qu'instances de NSMutableString.

NSJSONReadingAllowFragments:

Spécifie que l'analyseur doit autoriser les objets de niveau supérieur qui ne sont pas une instance de NSArray ou NSDictionary.

Note2 : J'ai trouvé ces définitions sur: https://developer.Apple.com/reference/foundation/nsjsonreadingoptions

Ma question est : Quelqu'un peut-il s'il vous plaît m'expliquer les différences entre ces options, à quoi dois-je les utiliser et si vous pouviez me montrer un exemple de code de ces options ce serait parfait :).

Toute aide appréciée.

Merci.

22
0ndre_

Réponse courte pour les deux premières options:

Ignorez-les dans Swift!

Dans Swift vous pouvez rendre les objets mutables simplement avec le mot clé var.

Dans Objective-C, d'autre part, vous avez besoin

  • NSJSONReadingMutableContainers pour rendre les types de collection imbriqués mutables NSArrayNSMutableArray et NSDictionaryNSMutableDictionary.
  • NSJSONReadingMutableLeaves pour rendre les chaînes de valeur mutables → NSMutableString.

Dans Objective-C et Swift si vous êtes seulement lecture le JSON que vous don pas besoin de mutabilité du tout.

La troisième option NSJSONReadingAllowFragments est importante si l'objet racine du JSON reçu est not un tableau et not un dictionnaire.
S'il s'agit est d'un tableau ou d'un dictionnaire, vous pouvez également omettre cette option.

La paire de supports vides [] représente No options (le paramètre options peut être omis dans Swift 3+).

32
vadian

Vous feriez mieux de savoir comment les valeurs JSON sont importées dans le monde iOS:

 JSON array ->  NSArray
 JSON object -> NSDictionary
 JSON number -> NSNumber
 JSON string -> NSString
 JSON true   -> NSNumber
 JSON false  -> NSNumber
 JSON null   -> NSNull

(Vous feriez mieux de vérifier également les RFC de JSON. RFC-4627 , RFC-7159 )

Revérifiez ensuite toutes les options:

mutableContainers (NSJSONReadingMutableContainers) :

Garantit que les NSArrays ou NSDictionarys contenus dans le résultat doivent être NSMutableArrays ou NSMutableDictionarys. Quelqu'un dit dans les anciens iOS JSONSerialization (NSJSONSerialization) a renvoyé des objets mutables sans spécifier mutableContainers, mais en fonction de cela n'est pas recommandé, et en fait, vous pouvez trouver des personnes signalant qu'un tel code ne le fait pas travailler dans iOS 10.

Dans Swift, la mutabilité est représentée par var et let, vous n'avez donc pas besoin d'utiliser cette option dans les codes Swifty. Nécessaire uniquement lorsque vous convertissez certaines parties du résultat désérialisé en NSMutableArray ou NSMutableDictionary. Je recommande fortement de réécrire ces codes d'une manière plus Swifty.

mutableLeaves (NSJSONReadingMutableLeaves) :

Garantit que les NSStrings contenus dans le résultat doivent être NSMutableStrings. Rarement utilisé même dans les anciens codes Objective-C, ignorez-le.

allowFragments (NSJSONReadingAllowFragments) :

Dans l'ancien RFC (RFC-4627), seuls le tableau et l'objet étaient valides en tant que composant le plus externe de JSON. Si vous attendez un tableau ou un objet (NSDictionary) du serveur, NE PAS spécifier cette option vous aidera à trouver un peu plus tôt la valeur retournée non valide du serveur.

Voir la différence de codes:

Présumer data1 est une représentation UTF-8 valide du JSON suivant:

[{"name": "aaa", "value": 123}, {"name": "bbb", "value": 456}]

Et le code:

do {
    let result = try JSONSerialization.jsonObject(with: data1)
    let resultArray = result as! NSMutableArray //->This may cause your app crash
    //->Could not cast value of type '__NSArrayI' (0x105e79c08) to 'NSMutableArray' (0x105e79cd0).
    print(resultArray)
} catch {
    print(error)
}

do {
    let result = try JSONSerialization.jsonObject(with: data1, options: [.mutableContainers])
    let resultArray = result as! NSMutableArray //->This should always work
    print(resultArray) //->shows output...
} catch {
    print(error)
}

Et data2:

-1

Et la comparaison pour cela:

do {
    let result = try JSONSerialization.jsonObject(with: data2)
    print(result)
} catch {
    print(error) //->Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}
}

do {
    let result = try JSONSerialization.jsonObject(with: data2, options: [.allowFragments])
    print(result) //-> -1
} catch {
    print(error)
}
18
OOPer

Options: [] est un tableau vide ne renvoie rien.

Tandis que Options: [] peut également être modifié avec:

  • NSJSONWritingOptions: pour écrire des données JSON comme.

    • NSJSONWritingOptions.NSJSONWritingPrettyPrinted: Spécifie que les données JSON doivent être générées avec des espaces conçus pour rendre la sortie plus lisible. Si cette option n'est pas définie, la représentation JSON la plus compacte possible est générée.
  • NSJSONReadingOptions: utilisé lors de la création d'objets Foundation à partir de données JSON.

    • NSJSONReadingOptions.MutableContainers: Spécifie que les tableaux et les dictionnaires sont créés en tant qu'objets mutables.
    • .mutableLeaves: Spécifie que les chaînes de feuilles du graphique d'objet JSON sont créées en tant qu'instances de NSMutableString.
    • .allowFragments: Spécifie que l'analyseur doit autoriser les objets de niveau supérieur qui ne sont pas une instance de NSArray ou NSDictionary.
4
vaibhav