Swift's JSONDecoder
bietet eine dateDecodingStrategy
Eigenschaft, die es uns erlaubt zu definieren, wie eingehende Datenfolgen in Übereinstimmung mit einem DateFormatter
Objekt interpretiert werden.
Ich arbeite jedoch derzeit mit einer API, die abhängig von der Eigenschaft sowohl Datumstrings ( yyyy-MM-dd
) als auch datetime Strings ( yyyy-MM-dd HH:mm:ss
) zurückgibt. Gibt es eine Möglichkeit, die JSONDecoder
dies zu behandeln, da das angegebene DateFormatter
-Objekt nur mit einem einzigen dateFormat
gleichzeitig umgehen kann?
Eine harmlose Lösung besteht darin, die begleitenden Decodable
-Modelle so umzuschreiben, dass sie nur Zeichenfolgen als ihre Eigenschaften akzeptieren und öffentliche Date
getter / setter-Variablen bereitstellen, aber das scheint mir eine schlechte Lösung zu sein. Irgendwelche Gedanken?
Es gibt einige Möglichkeiten, damit umzugehen:
DateFormatter
-Unterklasse erstellen, die zuerst das Datum / Uhrzeit-Zeichenfolgenformat versucht. Wenn dies fehlschlägt, wird das einfache Datumsformat .custom
Date
-Decodierungsstrategie angeben, in der Sie die Decoder
für eine singleValueContainer()
fragen, eine Zeichenkette dekodieren und sie durch die gewünschten Formatierungen übergeben, bevor Sie das analysierte Datum übergeben Date
-Typ erstellen, der eine benutzerdefinierte init(from:)
und encode(to:)
bietet, was dies tut (aber das ist nicht wirklich besser als eine .custom
Strategie) init(from:)
für alle Typen bereitstellen, die diese Daten verwenden und verschiedene Dinge dort versuchen Alles in allem werden die ersten beiden Methoden wahrscheinlich am einfachsten und saubersten sein - Sie werden die standardmäßige synthetisierte Implementierung von Codable
überall beibehalten, ohne die Typsicherheit zu opfern.
Angesichts dieses gleichen Problems habe ich folgende Erweiterung geschrieben:
%Vor%Diese Erweiterung ermöglicht es Ihnen, eine DateDecodingStrategy für den JSONDecoder zu erstellen, der mehrere unterschiedliche Datumsformate innerhalb derselben JSON-Zeichenfolge verarbeitet. Die Erweiterung enthält eine Funktion, die die Implementierung eines Abschlusses erfordert, der Ihnen einen CodingKey gibt, und es liegt an Ihnen, den richtigen DateFormatter für den bereitgestellten Schlüssel anzugeben.
Sagen wir, dass Sie folgendes JSON haben:
%Vor%Das folgende Struct:
%Vor%Um den JSON zu dekodieren, würden Sie den folgenden Code verwenden:
%Vor% Es gibt keine Möglichkeit, dies mit einem einzelnen Encoder zu tun. Am besten passen Sie hier die Methoden encode(to encoder:)
und init(from decoder:)
an und stellen Sie eine eigene Übersetzung für diese Werte bereit, wobei die integrierte Datumsstrategie für die andere beibehalten wird.
Es könnte sich lohnen, zu diesem Zweck einen oder mehrere Formatierer in das Objekt userInfo
zu übergeben.
Tags und Links swift json-deserialization codable