Проблема преобразования JSON Ints в строки (Swift 5) - PullRequest
0 голосов
/ 22 апреля 2020

плохо знаком со Swift и кодированием в целом. Попытка поместить массив JSON объектов в tableView. Возникли проблемы при преобразовании моих Ints в строки в методе detailTextView.text делегата tableView. Для получения ошибки «Initializer 'init (_ :)» требует, чтобы «Int?» соответствует 'LosslessStringConvertible.' "Попробуйте использовать это, но это кроличья нора ошибок оттуда. Большую часть дня просматривал, но не повезло.

class AllCountriesVC: UITableViewController {


    struct CovidData: Codable {
        let country: String
        let cases: Int?
        let todayCases: Int?
        let deaths: Int?
        let todayDeaths: Int?
        let recovered: Int?
        let active: Int?
        let critical: Int?
        let totalTests: Int?
    }


    var data = [CovidData]()

    override func viewWillAppear(_ animated: Bool) {
        load()
        self.tableView.reloadData()
    }


    override func viewDidLoad() {
        super.viewDidLoad() 
    }

    func load() {
        if let url = URL(string: "https://coronavirus-19-api.herokuapp.com/countries/") {
        let jsonData = try! Data(contentsOf: url)
            self.data = try! JSONDecoder().decode([CovidData].self, from: jsonData)

            self.tableView.reloadData()
        }
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count ?? 1       
    }
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        let countryData = data[indexPath.row]
        cell.textLabel?.text = countryData.country
        cell.detailTextLabel?.text = String(countryData.cases)
        //this is where it fails with error "Initializer 'init(_:)' requires that 'Int?' conform to 'LosslessStringConvertible'"

        return cell
    } 
}

1 Ответ

0 голосов
/ 22 апреля 2020

Из данных видно, что единственным свойством, которое имеет нулевые данные, является recovered, поэтому вы изменяете остальные свойства на необязательные. Это облегчит вам задачу.

Я бы также порекомендовал вам использовать do/try/catch вместо try!.

class AllCountriesVC: UITableViewController {
    struct CovidData: Codable {
        let country: String
        let cases: Int
        let todayCases: Int
        let deaths: Int
        let todayDeaths: Int
        let recovered: Int?
        let active: Int
        let critical: Int
        let totalTests: Int
    }


    var data = [CovidData]()

    override func viewWillAppear(_ animated: Bool) {
        load()
    }

    func load() {
        if let url = URL(string: "https://coronavirus-19-api.herokuapp.com/countries/") {
            do {
                let jsonData = try Data(contentsOf: url)
                self.data = try JSONDecoder().decode([CovidData].self, from: jsonData)

                self.tableView.reloadData()
            }
            catch {
                print(error)
            }
        }
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count ?? 1       
    }
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        let countryData = data[indexPath.row]
        cell.textLabel?.text = countryData.country
        cell.detailTextLabel?.text = String(countryData.cases)
        return cell
    } 
}

Если вы хотите использовать дополнительный, скажем recovered тогда вы можете использовать оператор объединения nil - ??

String(countryData.recovered ?? 0)
...