Swift - Parsing Data Error - Swift.DecodingError.dataCorrupted
Ich verwende SwiftSoup in Kombination mit Codable, um die richtigen Elemente zu erhalten und die Daten zu analysieren. Ich erhalte jedoch diesen Fehler:
JSON decode failed: Swift.DecodingError.dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value.})))
Ich habe online gesucht, sichergestellt, dass meine Daten korrekt übereinstimmen, sogar die erwarteten Typen von Int in String geändert, aber eine Fehlermeldung erhalten, dass ein Int erwartet wurde.
Dies sind die Daten, die ich empfange und in der Konsole drucken kann:
data -
{"test":0,"ppace":85,"pshooting":92,"ppassing":91,"pdribbling":95,"pdefending":38,"pphysical":65,"acceleration":91,"sprintspeed":80,"agility":91,"balance":95,"reactions":94,"ballcontrol":96,"dribbling":96,"positioning":93,"finishing":95,"shotpower":86,"longshotsaccuracy":94,"volleys":88,"penalties":75,"interceptions":40,"headingaccuracy":70,"marking":32,"standingtackle":35,"slidingtackle":24,"vision":95,"crossing":85,"freekickaccuracy":94,"shortpassing":91,"longpassing":91,"curve":93,"jumping":68,"stamina":72,"strength":69,"aggression":44,"composure":96}
Das ist meine Funktion:
func parseData() {
do {
let html = try String(contentsOf: url!, encoding: String.Encoding.ascii)
let doc: Document = try! SwiftSoup.parse(html)
let elements = try doc.getAllElements()
for element in elements {
switch element.id() {
case "player_stats_json":
let content = try! element.getElementsContainingText("ppace").text()
print(content.utf8)
let jsonData = content.data(using: .utf8)
do {
self.player = try JSONDecoder().decode(PlayerModel.self, from: Data(jsonData!))
} catch let jsonError as NSError {
print("JSON decode failed: \(jsonError)")
print("data - \(content)")
}
default:
break
}
}
} catch Exception.Error(type: let type, Message: let message) {
print(type)
print(message)
} catch {
print("")
}
}
Und das ist meine Modelldatei:
struct PlayerModel: Codable {
var test: Int
var ppace: Int
var pshooting: Int
var ppassing: Int
var pdribbling: Int
var pdefending: Int
var pphysical: Int
var acceleration: Int
var sprintspeed: Int
var agility: Int
var balance: Int
var reactions: Int
var ballcontrol: Int
var dribbling: Int
var positioning: Int
var finishing: Int
var shotpower: Int
var longshotsaccuracy: Int
var volleys: Int
var penalties: Int
var interceptions: Int
var headingaccuracy: Int
var marking: Int
var standingtackle: Int
var slidingtackle: Int
var vision: Int
var crossing: Int
var freekickaccuracy: Int
var shortpassing: Int
var longpassing: Int
var curve: Int
var jumping: Int
var stamina: Int
var strength: Int
var aggression: Int
var composure: Int
}
Ich habe doppelt und dreifach überprüft, ob die Variablennamen mit jedem Schlüssel übereinstimmen. Ich habe die ausgegebenen Daten in die Konsole in einen Online-JSON-Validator eingefügt, und es werden keine Fehler angezeigt. Ich kratzte mir jetzt wirklich am Kopf, weil ich nicht verstehen kann, wo ich falsch gelaufen bin.
Antworten
Ich habe immer noch keine Ahnung, was mit Ihrer Analyse falsch ist. Ich habe es geschafft, Ihr HTML zu analysieren, aber ich habe keine Ahnung, warum beim Versuch, Int anstelle von Uint8 zu verwenden, immer wieder nicht die richtigen Werte zurückgegeben wurden. Das hat bei mir funktioniert:
import UIKit
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true
struct PlayerModel: Codable {
let test: UInt8
let ppace: UInt8
let pshooting: UInt8
let ppassing: UInt8
let pdribbling: UInt8
let pdefending: UInt8
let pphysical: UInt8
let acceleration: UInt8
let sprintspeed: UInt8
let agility: UInt8
let balance: UInt8
let reactions: UInt8
let ballcontrol: UInt8
let dribbling: UInt8
let positioning: UInt8
let finishing: UInt8
let shotpower: UInt8
let longshotsaccuracy: UInt8
let volleys: UInt8
let penalties: UInt8
let interceptions: UInt8
let headingaccuracy: UInt8
let marking: UInt8
let standingtackle: UInt8
let slidingtackle: UInt8
let vision: UInt8
let crossing: UInt8
let freekickaccuracy: UInt8
let shortpassing: UInt8
let longpassing: UInt8
let curve: UInt8
let jumping: UInt8
let stamina: UInt8
let strength: UInt8
let aggression: UInt8
let composure: UInt8
}
let url = URL(string:"https://www.futbin.com/21/player/541/lionel-messi")!
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, let html = String(data: data, encoding: .utf8) else { return }
if let start = html.range(of: #"<div style="display: none;" id="player_stats_json">"#)?.upperBound,
let end = html[start...].range(of: #"</div>"#)?.lowerBound {
let json = html[start..<end]
do {
let player = try JSONDecoder().decode(PlayerModel.self, from: Data(json.utf8))
print(player)
} catch {
print(error)
}
}
}.resume()
Dies wird gedruckt
PlayerModel (Test: 0, ppace: 85, pshooting: 92, ppassing: 91, pdribbling: 95, pdefending: 38, pphysical: 65, beschleunigung: 91, sprintspeed: 80, agility: 91, balance: 95, reaktionen: 94, Ballkontrolle: 96, Dribbling: 96, Positionierung: 93, Finishing: 95, Schusskraft: 86, Longshots-Genauigkeit: 94, Volleys: 88, Strafen: 75, Interceptions: 40, Heading-Genauigkeit: 70, Markierung: 32, Standingtackle: 35, Slidingtackle: 24, Vision: 95, Kreuzung: 85, Freistoßgenauigkeit: 94, Kurzpass: 91, Langpass: 91, Kurve: 93, Springen: 68, Ausdauer: 72, Stärke: 69, Aggression: 44, Gelassenheit: 96)