2017-10-26 13 views
0

Ich weiß, dass dies in anderen Fragen abgedeckt wurde, aber ich habe ihnen gefolgt und bin immer noch ratlos. Hier ist meine JSON-Struktur:Swift 4 JSON Decoder

 { 
     "FindBoatResult": { 
     "num_boats": 10, 
     "boat": [ 
     { 
      "num_segments": 1, 
      "segments": [ 
       { 
       "ident": "String", 
       "origin" : { 
         "code" : "String" 
       }, 
      }, 
     ] 
     } 

etc ... aber das ist so tief wie die Struktur geht. In jeder JSON-Antwort gibt es mehrere Rückgaben von "Segmenten". In Swift habe ich diesen Code.

Dies schlägt fehl und wirft Fehler, aber Fehler druckt als nil..so ich kann nicht sagen, was ich vermisse. dataAsString gibt den JSON wie erwartet aus, also weiß ich, dass "Daten" gut sind.

+2

Sie müssen Fehler als 'print (Fehler)' –

+0

... drucken, oder um irgendeine Verwirrung zwischen dem Fehler zu vermeiden, der von 'dataTask' übergeben wird, würde ich ihm einen eindeutigen Namen geben, z. 'do {...} catch lassen Sie parseError {print (parseError)}'. – Rob

Antwort

1

Ich entdeckte ein paar kleinere Probleme. Versuchen Sie ersetzen diese:

struct FindBoatResult: Decodable { 
    let boats: Boats 
    let num_boats: Int 
} 
struct Boats: Decodable { 
    let segments: [Segments] 
} 

mit:

struct FindBoatResult: Decodable { 
    let boat: [Boat] 
    let num_boats: Int 
} 
struct Boat: Decodable { 
    let segments: [Segments] 
} 

Schließlich decode mit dem Result Typ (nicht FindBoatResult):

JSONDecoder().decode(Result.self, from: data) 
1

Aufbauend auf Paulo Antwort, könnte ich weiter vorschlagen, wenn Sie stecken fest mit JSON, das über Schlüssel verfügt, die den Swift-Konventionen für Eigenschaftsnamen nicht entsprechen. Verwenden Sie das CodingKeys-Muster, um JSON-Schlüssel in bett zu übersetzen er Swift Eigenschaftsnamen, z.B .:

struct BoatResult: Decodable {   // I'd simplify this name 
    let boatCollection: BoatCollection 

    enum CodingKeys: String, CodingKey { 
     case boatCollection = "FindBoatResult" 
    } 
} 

struct BoatCollection: Decodable {  // I'd simplify this, too, removing "Find" from the name; verbs are for methods, not properties 
    let boats: [Boat] 
    let numberOfBoats: Int 

    enum CodingKeys: String, CodingKey { 
     case boats = "boat"    // "boat" isn't great property name for an array of boats, so let's map the poor JSON key to better Swift name here 
     case numberOfBoats = "num_boats" // likewise, let's map the "_" name with better camelCase property name 
    } 
} 

struct Boat: Decodable {     // This entity represents a single boat, so let's use "Boat", not "Boats" 
    let segments: [Segment] 
} 

struct Segment: Decodable {    // This entity represents a single segment, so let's use "Segment", not "Segments" 
    let identifier: String 
    let origin: Origin 

    enum CodingKeys: String, CodingKey { 
     case identifier = "ident"  // `ident` isn't a common name for identifier, so let's use something more logical 
     case origin 
    } 
} 

struct Origin: Decodable { 
    let code: String 
} 

So zum Beispiel verwenden, um eine Plural (z boats), wenn Sie ein Array von Objekten darstellen, und verwenden Sie CodingKeys, um den irreführendenJSON-Schlüssel dieser besser benannten boats Array-Referenz zuzuordnen. Oder wenn Sie einen Schlüssel wie num_boats haben, fühlen Sie sich nicht wie Sie müssen diesen schlechten Namen in Ihrem Swift Eigentum verwenden und etwas besser wie numberOfBoats (oder count oder was auch immer), und verlieren die _ Syntax, die sehr unwissentlich ist.

Wenn Sie das Design des JSON unter Kontrolle haben, können Sie einfach einige dieser schlecht ausgewählten Schlüsselnamen korrigieren, aber auch wenn Sie möchten, dass Ihr Web-Service die _ Syntax verwendet, gehen Sie voran und verwende CodingKeys, um sicherzustellen, dass deine Swift-Objekte die camelCase-Konvention einhalten.

+0

Ich bin nicht sicher, warum Sie keine Frage stellen können. Wenn es ein S.O. Problem, suchen Sie dann einen anderen Ort für das Posten einer Frage. Wenn es sich um ein Arbeits-/Vertraulichkeitsproblem handelt, dann anonymisieren Sie die Frage ausreichend, um diese Bedenken auszuräumen. Aber versuchen, Ihr Problem hier in Kommentaren zu diagnostizieren, ist nicht der richtige Ort. Sie sollten die obigen Kommentare entfernen. – Rob