Betrachtet den folgenden Kern: https://gist.github.com/anonymous/0703a591f97fa9f6ad35b29234805fbd - keine effiziente Möglichkeit, alle relevanten Informationen anzuzeigen, da die Dateien von beträchtlicher Länge sind. EntschuldigungDecoding JSON-Objekt (Senden GET-Anfrage mit Parametern) - Swift 4 Decodable
Ich habe einige verschachtelte JSON-Objekte, die ich versuche zu dekodieren.
{
"establishments":[
{ ... }
],
"meta":{ ... },
"links":[
]
}
^Die establishments
Array enthält Establishment
Objekte
Mein Code erfolgreich ausgeführt wird, bis die Leitung 7 von ViewController.swift
, wo ich tatsächlich nutzen JSONDecode()
Funktionalität des Swift 4.
ViewController.swift
let jsonURLString = "http://api.ratings.food.gov.uk/Establishments?address=\(self.getPostalCode(place: place))&latitude=\(place.coordinate.latitude.description)&longitude=\(place.coordinate.longitude.description)&maxDistanceLimit=0&name=\(truncatedEstablishmentName[0].replacingOccurrences(of: "'", with: ""))"
guard let url = URL(string: jsonURLString) else { print("URL is invalid"); return }
URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in
guard let data = data, error == nil, response != nil else {
print("Something went wrong")
return
}
//print("test")
do {
let establishments = try JSONDecoder().decode(Establishments.self, from: data)
print(establishments)
} catch {
print("summots wrong")
}
}).resume()
Der Ausgang I für das zugeordnete JSON-Objekt in Establishment.swift
gesehen bekommen ist: summots wrong
- auf Linie 11 von ViewController.swift
.
Ich glaube, der Grund, es ist nicht wie erwartet funktioniert, weil das JSON-Format wie so ist:
{
"establishments":[ ... ],
"meta":{ ... },
"links":[ ]
}
aber ich weiß nicht, ob meine Klassenstruktur /, was ich in meinen Ansicht-Controller zu tun erfüllt diese Layoutkriterien.
Kann mir jemand sehen, wo ich falsch liege? Ich denke, es ist etwas sehr einfach, aber ich kann meinen Kopf nicht scheinen, um es zu bekommen
Ich verstehe auch, dass ich nicht zu nennen Attribute von Klassen mit einem Großbuchstaben soll ich - entschuldigen uns für die Konventionen brechen
EDIT: ich druckte den Fehler statt meiner eigenen Aussage und es ist wie folgt:
statt: print("summots wrong")
ich schrieb: print(error)
dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.})))
Wie Hamish richtig bemerkte, erhalte ich keine korrekten JSON-Daten von der GET-Anfrage. Tatsächlich erhalte ich überhaupt kein JSON. Die verwendete API verwendet standardmäßig das XML-Format, wenn x-api-version
nicht auf 2
eingestellt ist.
Statt //print("test")
in meiner ViewController.swift
Datei, habe ich die empfohlene: print(String(data: data, encoding: .utf8))
Linie
I Postman mit den folgenden Header verwendet: x-api-version: 2
, accept: application/json
und content-type: application/json
meine JSON Ausgabe abrufen. Wenn ich die gleiche GET-Zeichenfolge (mit allen Parametern richtig ausgefüllt) in meinem Browserfenster verwende, erhalte ich eine Fehlermeldung: The API 'Establishments' doesn't exist
in einem XML-Format.
Gibt es eine Möglichkeit für mich, einen Header mit dieser URL zu senden?
EDIT 2: Ich habe die Anforderung geändert URLRequest
statt nur URL
zu verwenden.
Hier ist meine aktualisierte ViewController.swift
Code:
let jsonURLString = "http://api.ratings.food.gov.uk/Establishments?address=\(self.getPostalCode(place: place))&latitude=\(place.coordinate.latitude.description)&longitude=\(place.coordinate.longitude.description)&maxDistanceLimit=0&name=\(truncatedEstablishmentName[0].replacingOccurrences(of: "'", with: ""))"
guard let url = URL(string: jsonURLString) else { print("URL is invalid"); return }
var request = URLRequest(url: url)
request.httpMethod = "GET"
request.addValue("x-api-version", forHTTPHeaderField: "2")
request.addValue("accept", forHTTPHeaderField: "application/json")
request.addValue("content-type", forHTTPHeaderField: "application/json")
URLSession.shared.dataTask(with: request, completionHandler: { (data, response, error) in
guard let data = data, error == nil, response != nil else {
print("Something went wrong")
return
}
print(String(data: data, encoding: .utf8))
// do {
// let establishments = try JSONDecoder().decode(Establishments.self, from: data)
// print(establishments)
// } catch {
// print(error)
// }
}).resume()
ich den Fehler bekommen: HTTP Error 400. The request has an invalid header name
ich einige Prüfungen haben es die Anforderung ignoriert einfach den x-api-version
Header-Wert von 2.
Irgendwelche Ideen?
EDIT 3: Das richtige Format für addValue
hätte sein sollen: request.addValue("2", forHTTPHeaderField: 'x-api-version
und so weiter.
Ich bin jetzt konfrontiert mit einem Problem mit meiner Klasse Erklärung, speziell in meiner 'Meta' Klasse.
Meta.(CodingKeys in _DF4B170746CD5543281B14E0B0E7F6FB).dataSource], debugDescription: "Expected String value but found null instead.", underlyingError: nil
Es beschwert, weil meine Klassendeklaration aus dem JSON-Objekt es erwartet wird, die Daten nicht übereinstimmen.
In meiner JSON-Antwort (auf den Kern bezieht) gibt es zwei meta
Objekte, enthält man den Wert von null
für dataSource
und die anderen Lucene
zu sein.
Gibt es eine Möglichkeit für mich, Null-Werte sowie Strings in meinen Initialisierern zu akzeptieren, alles unter Einhaltung des Decodable-Protokolls?
Dieser Abschnitt der JSON-Antwort ist für mich tot, muss ich noch Objekte dafür erstellen, oder kann ich einfach damit davonkommen, sie zu ignorieren? - ohne irgendetwas zu erklären. Oder muss ich speziell alles in der JSON-Antwort notieren, um die Daten verwenden zu können?
Kopieren Sie bitte die relevanten Teile Ihres Codes (vorzugsweise ein [mcve]) und fügen Sie sie in den Fragenkörper selbst ein, anstatt eine Verknüpfung zu einem Kernpunkt herzustellen. Es ist nicht zu erwarten, dass wir diese Seite verlassen, um Ihre Frage zu verstehen. – Hamish
Danke für die konstruktive Kritik Jungs, ich habe ein paar Änderungen an der Frage gemacht –
Ich lief die JSON-Ausgabe über einen JSON-Validator und alles scheint gültig zu sein. Irgendwelche Ideen? : \ –