Je dois désérialiser une chaîne JSON comme ceci:
{ "name" : "John Smith", "value" : "someValue" }
dans Swift 4, où "value" doit être une énumération et l'objet entier est une structure comme:
struct MyType {
name: String?
value: Value?
}
À un moment donné dans le futur, de nouvelles valeurs d'énumération pourraient être ajoutées dans le backend, alors j'ai pensé qu'il serait judicieux d'avoir une solution de secours.
J'ai pensé que je pourrais créer une énumération comme
enum Value {
case someValue
case someOtherValue
case unknown(value: String)
}
mais je ne peux tout simplement pas comprendre comment désérialiser cette énumération et la faire fonctionner. Auparavant, j'utilisais simplement une String
énumération, mais la désérialisation des valeurs inconnues lève des erreurs.
Existe-t-il un moyen simple de faire fonctionner cela ou dois-je désérialiser la valeur en tant que a String
et créer un getter personnalisé dans la structure avec une instruction switch pour renvoyer l'un des cas (probablement même pas dans la structure elle-même mais dans mon modèle de vue)?
Vous pouvez implémenter init(from decoder: Decoder)
et encode(to encoder: Encoder)
gérer chaque cas explicitement, c'est-à-dire
struct MyType: Codable {
var name: String?
var value: Value?
enum CodingKeys: String, CodingKey {
case name
case value
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
name = try values.decode(String.self, forKey: .name)
let strValue = try values.decode(String.self, forKey: .value)
//You need to handle every case explicitly
switch strValue {
case "someValue":
value = Value.someValue
case "someOtherValue":
value = Value.someOtherValue
default:
value = Value.unknown(value: strValue)
}
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(name, forKey: .name)
if let val = value {
//You need to handle every case explicitly
switch val {
case .someValue, .someOtherValue:
try container.encode(String(describing: val), forKey: .value)
case .unknown(let strValue):
try container.encode(strValue, forKey: .value)
}
}
}
}
enum Value {
case someValue
case someOtherValue
case unknown(value: String)
}
Cet article est collecté sur Internet, veuillez indiquer la source lors de la réimpression.
En cas d'infraction, veuillez [email protected] Supprimer.
laisse moi dire quelques mots