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.
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.
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
.