Bisher habe ich eigentlich immer SwiftyJSON verwendet, wenn ich kompliziertes JSON-Dateien verarbeiten wollte. Mit Swift 4 haben die Entwickler bei Apple jedoch eine deutliche Verbesserung der „Hausmittel“ gebracht. Ganz so simpel wie SwiftyJSON ist es aus meiner Sicht nicht, aber jede Abhängigkeit, die man weglassen kann, ist ein Vorteil.

Für dieses Beispiel nehmen wir uns also eine einfache API vor. In diesem Fall die Wetter API von Yahoo und wir hätten gerne die Temperatur für Otzberg. Die API Abfrage geht recht einfach und liegt hinter diesem Link.

https://query.yahooapis.com/v1/public/yql?q=select%20item.condition.temp%20from%20weather.forecast%20where%20woeid%20in%20(select%20woeid%20from%20geo.places(1)%20where%20text%3D%22Otzberg%2C%20Germany%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys

Was dabei rauskommt ist eine recht einfache Antwort, die dennoch einige Hierarchien tief liegt. Die Tiefe hat auch ihren Sinn, meine Abfrage hat ganz viel „weggeworfen“, was sonst ausgegeben hätte werden können.

{
  "query": {
    "count": 1,
    "created": "2018-04-28T08:18:27Z",
    "lang": "de-de",
    "results": {
      "channel": {
        "item": {
          "condition": {
            "temp": "56"
          }
        }
      }
    }
  }
}

Wie kommt man also an die Temperatur? Der von mir gewählte Weg – sicher nicht der Beste – sieht vor, dass ich mir mehrere Codable Structs anlegte und zwar für jede Hierarchie eine:

struct Forecast: Codable {
    let query : Query
}

struct Query : Codable {
    let count : Int?
    let created : String?
    let lang : String?
    let results : Results
}

struct Results : Codable {
    let channel : Channel
}

struct Channel : Codable{
    let item : Item
}

struct Item : Codable{
    let condition : Condition
}

struct Condition: Codable{
    let temp : String?
}

Im struct für Query habe ich mir auch die Daten für Count & Co rausgezogen, auch wenn ich die eigentlich nicht verwenden will. Aber vollständig ist halt vollständig ;)  Der Zugriff auf die Temperatur ist dann eigentlich gar nicht mehr kompliziert und mir gefällt die Tatsache, dass ich die Struktur meiner JSON Antwort oben so deutlich klar gemacht habe.

if jsonString != nil{
    let decoder = JSONDecoder()
    let temp = try! decoder.decode(Forecast.self, from: jsonString!)
    print("\(temp.query.results.channel.item.condition.temp!) °F")
}

Ist das jetzt ne Menge Quelltext für einen einzigen Wert? Keine Frage. In PHP würde man das JSON Object mit json_decode() parsen und dann einfach den Wert auslesen, so nach dieser Art:

$forecast = json_decode($jsonString, true);
$tmp = $forecast["query"]["results"]["channel"]["item"]["condition"]["temp"];

Swift ist jedoch eine „strongly typed“ Programmiersprache, d.h. dass eine Variable entweder ein String oder ein Int ist, aber eben nicht einfach wechselt, wie das in PHP, JavaScript & Co möglich ist. Das macht die Arbeit mit Swift ein wenig „nervig“, aber auch sehr zuverlässig. Deine Variable ist immer genau das, was Du vorgegeben hast. Es gibt andere, die das Argument besser machen, als ich das je können werde.

Der Artikel ist eher für meine Erinnerung, als alles andere. Wenn er Dir trotzdem geholfen hat, lass es mich ruhig wissen.


Claus Wolf

Seit 1994 im Netz unterwegs und seit 2004 eingefleischter Mac-Nutzer.

0 Kommentare

Schreibe einen Kommentar

Avatar-Platzhalter

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.