enum PostType: Decodable {
init(from decoder: Decoder) throws {
// What do i put here?
}
case Image
enum CodingKeys: String, CodingKey {
case image
}
}
Co mam zrobić, aby to zakończyć? Powiedzmy też, że zmieniłem na case
to:
case image(value: Int)
Jak dostosować to do Decodable?
EDYTUJ Oto mój pełny kod (który nie działa)
let jsonData = """
{
"count": 4
}
""".data(using: .utf8)!
do {
let decoder = JSONDecoder()
let response = try decoder.decode(PostType.self, from: jsonData)
print(response)
} catch {
print(error)
}
}
}
enum PostType: Int, Codable {
case count = 4
}
Ostateczna edycja Poza tym, jak to obsłuży takie wyliczenie?
enum PostType: Decodable {
case count(number: Int)
}
iOS 13.3
. TestujęiOS 13.3
iiOS 12.4.3
zachowują się inaczej. PodiOS 13.3
, enum może być kodowane / dekodowane wyłącznie.Jak sprawić, by wyliczenia ze skojarzonymi typami były zgodne z
Codable
Ta odpowiedź jest podobna do @Howard Lovatt's, ale unika tworzenia
PostTypeCodableForm
struktury i zamiast tego używaKeyedEncodingContainer
typu dostarczonego przez firmę Apple jako właściwości wEncoder
iDecoder
, co ogranicza szablonowość.Ten kod działa dla mnie na Xcode 9b3.
źródło
Either
do kodowaniaSwift wyrzuci
.dataCorrupted
błąd, jeśli napotka nieznaną wartość wyliczenia. Jeśli Twoje dane pochodzą z serwera, może wysłać Ci nieznaną wartość wyliczenia w dowolnym momencie (po stronie serwera błędów, nowy typ dodany w wersji API i chcesz, aby poprzednie wersje Twojej aplikacji radziły sobie z wdzięcznością itp.) lepiej być przygotowanym i zakodować „styl obronny”, aby bezpiecznie dekodować wyliczenia.Oto przykład, jak to zrobić, z powiązaną wartością lub bez
I jak to wykorzystać w otaczającej strukturze:
źródło
Aby rozszerzyć odpowiedź @ Toka, możesz również dodać nieprzetworzoną reprezentowalną wartość do wyliczenia i użyć domyślnego opcjonalnego konstruktora do zbudowania wyliczenia bez
switch
:Można go rozszerzyć za pomocą własnego protokołu, który pozwala na refaktoryzację konstruktora:
Można go również łatwo rozszerzyć w celu zgłaszania błędu, jeśli określono nieprawidłową wartość wyliczenia, zamiast domyślnej wartości. Streszczenie tej zmiany jest dostępne tutaj: https://gist.github.com/stephanecopin/4283175fabf6f0cdaf87fef2a00c8128 .
Kod został skompilowany i przetestowany przy użyciu Swift 4.1 / Xcode 9.3.
źródło
Wariantem odpowiedzi @ proxpero, czyli terser, byłoby sformułowanie dekodera jako:
Dzięki temu kompilator może wyczerpująco zweryfikować przypadki, a także nie pomija komunikatu o błędzie w przypadku, gdy zakodowana wartość nie jest zgodna z oczekiwaną wartością klucza.
źródło
W rzeczywistości powyższe odpowiedzi są naprawdę świetne, ale brakuje w nich niektórych szczegółów potrzebnych wielu osobom w stale rozwijanym projekcie klient / serwer. Tworzymy aplikację, podczas gdy nasz backend nieustannie ewoluuje w czasie, co oznacza, że niektóre przypadki wyliczenia zmienią tę ewolucję. Potrzebujemy więc strategii dekodowania wyliczeń, która jest w stanie dekodować tablice wyliczeń, które zawierają nieznane przypadki. W przeciwnym razie dekodowanie obiektu zawierającego tablicę po prostu się nie powiedzie.
To, co zrobiłem, jest dość proste:
Bonus: Ukryj implementację> Uczyń z niej kolekcję
Ukrywanie szczegółów implementacji jest zawsze dobrym pomysłem. Do tego potrzebujesz trochę więcej kodu. Sztuczka polega na dostosowaniu
DirectionsList
sięCollection
i uczynieniu swojej wewnętrznejlist
tablicy prywatną:Możesz przeczytać więcej o dostosowywaniu się do niestandardowych kolekcji w tym poście na blogu Johna Sundella: https://medium.com/@johnsundell/creating-custom-collections-in-swift-a344e25d0bb0
źródło
Możesz robić, co chcesz, ale jest to trochę skomplikowane :(
źródło