Swift - Parsing Data Error - Swift.DecodingError.dataCorrupted

Oct 09 2020

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

2 LeoDabus Oct 09 2020 at 21:25

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)