2017-09-23 4 views
2

Ich versuche herauszufinden, warum die Verwendung optionaler URLs meine JSON-Decodierung mit Swift 4 fehlschlagen lässt. Ich habe bereits das WWDC-Video "Whats new in Foundation" ausgegossen. Äpfel Spielplatz Beispiele und eine Menge von Orten im Internet, aber haben keine Lösung gefunden.Optionale URLs, die JSON-Decodierung in Swift 4 unmöglich machen.

Dies ist ein Test, den ich erstellt habe, um das Problem zu zeigen. Sagen, das ist meine Json Daten:

let json = """ 
{ 
    "kind" : "", 
    "total" : 2, 
    "image_url" : "https://www.myawesomeimageURL.com/awesomeImage.jpg" 
} 
""".data(using: .utf8)! 

Und das ist mein struct:

struct BusinessService: Decodable { 
    let kind: String? 
    let total: Int 
    let image_url : URL? 
} 

Und hier ist, wo ich es serialisiert:

let myBusiness = try? JSONDecoder().decode(BusinessService.self, from: json) 
print(myBusiness) 

Nun ist das Problem, wenn ich json erhalten Daten, wo image_url fehlt, schlägt die JSON-Decodierung fehl und gibt mir null.

Ich bin verwirrt, warum "Art" eine optionale Zeichenfolge sein kann und nicht die JSON-Decodierung fehlschlagen, wenn es keinen Wert hat, aber Image_URL kann keine optionale URL sein, ohne dass der JSON fehlschlagen.

Ich habe versucht, dies für zwei Tage jetzt ohne Glück herauszufinden. Hat jemand einen Einblick, warum das scheitern würde?

Ich habe ein weiteres Puzzleteil bemerkt, und das ist die image_url in der JSON muss eigentlich keine gültige Bild-URL sein. Ich kann eine beliebige Zeichenfolge eingeben und meine Struktur wird serialisiert, also denke ich vielleicht, dass ich falsch verstehe, wie das funktioniert. Ich dachte, dass die URL automatisch nur dann gefüllt würde, wenn sie in eine gültige URL konvertiert werden könnte und das nicht geschieht.

Jeder Einblick in dieses würde sehr geschätzt werden.

Antwort

2

Das funktioniert für mich wie erwartet. Einstellen image_url zu null oder Weglassen führt vollständig zu einem gültigen BusinessService immer mit einem nil Wert für das image_url Feld decodiert:

struct Example: Decodable { 
    let url: URL? 
} 

// URL is present. This works, obviously. 
try JSONDecoder().decode(Example.self, from: """ 
    { "url": "foo" } 
    """.data(using: .utf8)!) 

// URL is missing, indicated by null. Also works. 
try JSONDecoder().decode(Example.self, from: """ 
    { "url": null } 
    """.data(using: .utf8)!) 

// URL is missing, not even the key is present. Also works. 
try JSONDecoder().decode(Example.self, from: """ 
    {} 
    """.data(using: .utf8)!) // works, too 

Das einzige Problem kommt, wenn ich einen ungültigen URL-Wert wie eine leere Zeichenfolge liefere für das Feld. Also ich denke, das ist dein Problem?

// This throws: "Invalid URL string." 
try JSONDecoder().decode(Example.self, from: """ 
    { "url": "" } 
    """.data(using: .utf8)!) 

Sie haben einen „none“ Wert für das URL-Feld zu senden, indem null oder verlassen die ganze Zeile aus zu senden, nicht eine leere Zeichenfolge senden.

Ich bin verwirrt, warum „Art“ eine optionale Zeichenfolge sein kann und nicht die json Decodierung fehlschlagen, wenn es keinen Wert hat, noch image_url kann nicht eine optionale URL sein, ohne dass die json zum Scheitern verurteilt.

Der Unterschied besteht darin, dass "" in JSON ein gültiger String Wert ist, aber keine gültige URL.

+0

Vielen Dank für die Erklärung. Das hat mich das ganze Wochenende verrückt gemacht. Ich arbeite nicht viel mit JSON, also wusste ich nicht, dass null ein gültiger Wert war. Es ist eine Schande, dass die API, die ich verwende (Yelp) übergibt "" anstelle von null. Ich muss in die JSON-Container schauen (denke ich), um dieses Problem zu lösen. Danke für die Hilfe! – SN81

+0

Gerne helfen!Die "leeren" Fälle sind immer ein bisschen schwierig, da es leicht ist, eine leere Zeichenfolge und eine fehlende Zeichenfolge zu verwechseln. Der 'Optional'-Typ in Swift macht dies etwas besser, da Sie' .none' erhalten, wenn die Zeichenfolge fehlt, und '.some (" ")', wenn die Zeichenfolge vorhanden, aber leer ist. Das Übergeben von "" für fehlende URLs ist in der Tat eine schlechte Wahl. – zoul

Verwandte Themen