2

I am trying to decode a JSON object, from this website: https://www.thesportsdb.com/api/v1/json/1/search_all_leagues.php?c=France&s=Soccer

I would like to store them in an array of Soccer elements, and show them in cells.

This is the code I did, but I have key not found errors, how is that possible?

class Soccer: Codable {
    
    var strLeague: String
    var strDescriptionEN: String
    var strBadge: String
    var strDivision: String
    var intFormedYear: String
    var strCountry: String
    
    init(strLeague: String, strDescriptionEN: String, strBadge: String, strDivision: String, intFormedYear: String, strCountry: String) {
        self.strLeague = strLeague
        self.strDescriptionEN = strDescriptionEN
        self.strBadge = strBadge
        self.strDivision = strDivision
        self.intFormedYear = intFormedYear
        self.strCountry = strCountry
    }
}
class SoccerTVC: UITableViewController {
    
    var leagues = [Soccer]()

    func download(at url: String, handler: @escaping (Data?) -> Void)
    {
        // 1 - Create URL
        guard let url = URL(string: url) else {
            debugPrint("Failed to create URL")
            handler(nil)
            return
        }
        // 2 - Create GET Request
        var request: URLRequest = URLRequest(url: url)
        request.httpMethod = "GET"
        // 3 - Create download task, handler will be called when request ended
        let task = URLSession.shared.dataTask(with: request) {
            (data, response, error) in handler(data)
        }
        task.resume()
    }
    
    func getSoccer() {
        // 1 - Download Soccer
        download(at: "https://www.thesportsdb.com/api/v1/json/1/search_all_leagues.php?c=France&s=Soccer")
        { (SoccerData) in
            if let Soccerdata = SoccerData {
                // 2 - Decode JSON into a array of Game object
                let decoder: JSONDecoder = JSONDecoder()
                do {
                    let jsonData = [try decoder.decode(Soccer.self, from: Soccerdata)]
                    self.leagues = jsonData
                    debugPrint(self.leagues)
                    
                    DispatchQueue.main.sync {
                        self.tableView.reloadData()
                    }
                }
                catch {
                    debugPrint("Failed to parse data - error: \(error)")
                }
            }
            else
            {
                debugPrint("Failed to get soccer data")
            }
        }
    }
    
    override func viewDidLoad() {
        getSoccer()
        super.viewDidLoad()
    }
}

Error message:

Failed to parse data - error: keyNotFound(CodingKeys(stringValue: "strLeague", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"strLeague\", intValue: nil) (\"strLeague\").", underlyingError: nil))

pawello2222
  • 46,897
  • 22
  • 145
  • 209
volvic2L
  • 35
  • 1
  • 5
  • 1
    That's not how you suppose to initialize a codable. – Desdenova Jun 25 '20 at 13:43
  • Here read this. https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types – Desdenova Jun 25 '20 at 13:45
  • 2
    Paste your json into [app.quicktype.io](https://app.quicktype.io) and it will give you the correct structs to use for decoding. – koen Jun 25 '20 at 13:54

2 Answers2

0

Your desired values is in country array key so you need to change your struct with :

struct Soccer: Codable {
  let countrys : [Country]?
}

  struct Country : Codable{
  var strLeague: String
  var strDescriptionEN: String
  var strBadge: String
  ....
      }

And you need to change your json decoder like :

 var leagues = [Country]()

 let jsonData = try decoder.decode(Soccer.self, from: Soccerdata)
 self.leagues = jsonData.countrys

  }
Omer Tekbiyik
  • 4,255
  • 1
  • 15
  • 27
0

Try this instead:

let jsonData = try JSONDecoder().decode([String:[Soccer]].self, from: Soccerdata)
self.leagues = jsonData.values
pawello2222
  • 46,897
  • 22
  • 145
  • 209