web-dev-qa-db-fra.com

Swift Codable traitement des valeurs nulles

J'ai une structure qui analyse JSON en utilisant Codable.

struct Student: Codable {
    let name: String?
    let amount: Double?
    let adress: String?
}

Désormais, si la valeur du montant arrive à l'état null, l'analyse JSON échoue.

Donc, devrais-je gérer manuellement les observations nulles pour tous les Int et Double présents dans la structure Student?

Les valeurs String entrant comme null sont automatiquement gérées.

3
Ekra

Laissez-moi faire ce terrain de jeu pour vous, car un exemple montre plus d'une centaine de mots:

import Cocoa

struct Student: Codable {
    let name: String?
    let amount: Double?
    let adress: String?
}

let okData = """
{
   "name": "here",
 "amount": 100.0,
 "adress": "woodpecker avenue 1"
}
""".data(using: .utf8)!

let decoder = JSONDecoder()
let okStudent = try decoder.decode(Student.self, from:okData)
print(okStudent)

let nullData = """
{
   "name": "there",
 "amount": null,
"adress": "grassland 2"
}
""".data(using: .utf8)!

let nullStudent = try decoder.decode(Student.self, from:nullData)
print(nullStudent)

null est parfaitement géré si vous définissez vos structures à l’aide d’options. Je le déconseillerais toutefois si vous pouviez l'éviter. Swift fournit le meilleur soutien que je connaisse pour m'aider pas à oublier de traiter les cas nil où qu'ils se produisent, mais ils restent pénibles.

6
Patru

Je parcourais Codable et j'ai eu ce problème.

Pour être très clair ici, il est, Si le JSON/réponse contient null comme valeur, il est interprété comme nil. C'est pourquoi l'une des propriétés du modèle pouvant contenir null doit être marquée comme facultative.

Par exemple, considérons la réponse JSON ci-dessous,

{
"name": "Steve",
"amount": null,
"address": "India"
}

Le modèle doit être comme ci-dessous, car cos amount renvoie null.

struct Student: Codable {
    let name: String
    let amount: Double?
    let address: String
}

Suggestion: Dans le cas où vous voudriez écrire une init(from decoder: Decoder) throws, utilisez toujours quelque chose comme ci-dessous, pour les propriétés facultatives.

init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        amount = try values.decodeIfPresent(String.self, forKey: .amount)
        //so on...
    }

Même si vous ajoutez un bloc do-catch avec try? decoder...., il peut être capturé en cas d'échec. J'espère que c'est clair !! Il est simple mais très difficile de trouver le problème, même si le modèle contient 5 propriétés ou plus, certaines contenant des valeurs null.

0
Vinayak GH