Ich bin auf diese Frage gestoßen und habe genau das Gleiche gesucht. Die Antworten, die ich fand, waren nicht sehr zufriedenstellend, obwohl ich befürchtete, dass die Lösungen hier die einzige Option sein würden.
In meinem Fall würde das Erstellen eines benutzerdefinierten Decoders eine Menge Boilerplate erfordern, die schwer zu warten wäre, sodass ich weiter nach anderen Antworten suchte.
Ich bin auf diesen Artikel gestoßen, der einen interessanten Weg zeigt, dies in einfachen Fällen mit a zu überwinden @propertyWrapper
. Das Wichtigste für mich war, dass es wiederverwendbar war und nur minimales Refactoring des vorhandenen Codes erforderte.
Der Artikel geht von einem Fall aus, in dem eine fehlende boolesche Eigenschaft standardmäßig auf false gesetzt werden soll, ohne dass dies fehlschlägt, zeigt aber auch andere unterschiedliche Varianten an. Sie können es genauer lesen, aber ich werde zeigen, was ich für meinen Anwendungsfall getan habe.
In meinem Fall hatte ich eine array
, die ich als leer initialisieren wollte, wenn der Schlüssel fehlte.
Also habe ich die folgenden @propertyWrapper
und zusätzliche Erweiterungen deklariert :
@propertyWrapper
struct DefaultEmptyArray<T:Codable> {
var wrappedValue: [T] = []
}
//codable extension to encode/decode the wrapped value
extension DefaultEmptyArray: Codable {
func encode(to encoder: Encoder) throws {
try wrappedValue.encode(to: encoder)
}
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
wrappedValue = try container.decode([T].self)
}
}
extension KeyedDecodingContainer {
func decode<T:Decodable>(_ type: DefaultEmptyArray<T>.Type,
forKey key: Key) throws -> DefaultEmptyArray<T> {
try decodeIfPresent(type, forKey: key) ?? .init()
}
}
Der Vorteil dieser Methode besteht darin, dass Sie das Problem im vorhandenen Code leicht beheben können, indem Sie das einfach @propertyWrapper
zur Eigenschaft hinzufügen . In meinem Fall:
@DefaultEmptyArray var items: [String] = []
Ich hoffe, dies hilft jemandem, der sich mit dem gleichen Problem befasst.
AKTUALISIEREN:
Nachdem ich diese Antwort gepostet hatte, während ich mich weiter mit der Angelegenheit befasste, fand ich diesen anderen Artikel, aber vor allem die jeweilige Bibliothek, die einige gängige, einfach zu verwendende @propertyWrapper
s für diese Art von Fällen enthält:
https://github.com/marksands/BetterCodable