Natknąłem się na to pytanie, szukając dokładnie tego samego. Odpowiedzi, które znalazłem, nie były zbyt satysfakcjonujące, mimo że obawiałem się, że rozwiązania tutaj będą jedyną opcją.
W moim przypadku stworzenie niestandardowego dekodera wymagałoby mnóstwa gotowych rozwiązań, które byłyby trudne do utrzymania, więc szukałem innych odpowiedzi.
Natrafiłem na ten artykuł, który pokazuje interesujący sposób na przezwyciężenie tego w prostych przypadkach przy użyciu pliku @propertyWrapper
. Najważniejsze dla mnie było to, że był on wielokrotnego użytku i wymagał minimalnej refaktoryzacji istniejącego kodu.
W artykule przyjęto przypadek, w którym chciałbyś, aby brakująca właściwość logiczna miała domyślnie wartość false bez błędu, ale pokazuje również inne różne warianty. Możesz przeczytać to bardziej szczegółowo, ale pokażę, co zrobiłem dla mojego przypadku użycia.
W moim przypadku miałem array
, że chciałem zostać zainicjowany jako pusty, jeśli brakowało klucza.
Dlatego zadeklarowałem następujące @propertyWrapper
i dodatkowe rozszerzenia:
@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()
}
}
Zaletą tej metody jest to, że można łatwo rozwiązać problem w istniejącym kodzie, po prostu dodając @propertyWrapper
do właściwości. W moim przypadku:
@DefaultEmptyArray var items: [String] = []
Mam nadzieję, że pomoże to komuś, kto ma ten sam problem.
AKTUALIZACJA:
Po opublikowaniu tej odpowiedzi, kontynuując badanie sprawy, znalazłem ten inny artykuł, ale co najważniejsze, odpowiednią bibliotekę, która zawiera kilka popularnych, łatwych w użyciu @propertyWrapper
plików do tego rodzaju przypadków:
https://github.com/marksands/BetterCodable