【问题标题】:Trouble converting JSON Ints to Strings (Swift 5)将 JSON 整数转换为字符串时遇到问题 (Swift 5)
【发布时间】:2020-08-05 02:54:58
【问题描述】:

Swift 新手和一般的编码。试图将一组 JSON 对象放入 tableView。在 tableView 委托方法的 detailTextView.text 中将我的 Ints 转换为字符串时遇到问题。收到错误“初始化程序 '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
    } 
}

【问题讨论】:

  • countryData.cases 是可选的:可以为零。您使用的String.init(_:) 期望一个非可选的Int。因此,如果它为 nil,则可以使用默认值,例如 0:String(countryData.cases ?? 0):即:如果 countryData.cases 为 nil,则使用 0,否则使用 countryData.cases 并使用“确定存在”(非可选)值初始化一个字符串.
  • numberOfRowsInSection 中的 nil 合并运算符毫无意义。你没注意到警告⚠️吗?
  • Larme,成功了,谢谢!!瓦迪安,我确实注意到了。被教导将其保留在那里作为故障保险。
  • 老师错了。非可选不能是nil,从不。

标签: ios json swift type-conversion


【解决方案1】:

通过查看数据,唯一具有空数据的属性是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)

【讨论】:

  • 做到了。太感谢了!!也感谢 do/catch 块的提示。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-25
  • 2017-02-24
  • 2019-07-23
  • 1970-01-01
相关资源
最近更新 更多