从 JSON 填充 UITableView

Populating UITableView from JSON

我正在尝试使用 JSON 文件在我的应用程序中填充 UITableView。以前我对一组样本数据进行硬编码,但需要转而使用我的 JSON 文件。这是在 SO 上找到的各种教程和答案的大杂烩,所以如果语法约定有一点偏差,我深表歉意。

import UIKit
import os.log

class BonusTableViewController: UITableViewController {

    //MARK: Properties
    var bonuses = [Bonus]() // Used for old sample data
    var jBonuses = [Bonuses]() // Used with JSON based data

    override func viewDidLoad() {
        super.viewDidLoad()

    //MARK: Confirm JSON file was loaded and log the Bonus Codes
        let loadedBonuses = loadJson(filename: "BonusData")
        for bonus in loadedBonuses! {
            print(bonus.bonusCode)
        }
    }

    // Load the JSON file from the bundled file.
    func loadJson(filename fileName: String) -> [Bonuses]? {
        if let url = Bundle.main.url(forResource: fileName, withExtension: "json") {
            do {
                let data = try Data(contentsOf: url)
                let decoder = JSONDecoder()
                let jsonData = try decoder.decode(JSONData.self, from: data)
                print("loadJson loaded JSON")
                return jsonData.bonuses
            } catch {
                print("error:\(error)")
            }
        }
        return nil
    }

    // MARK: Data Structures
    // Bonus Data Structs
    struct JSONData: Decodable {
        let name: String
        let version: String
        let bonuses: [Bonuses]
    }
    struct Bonuses: Decodable {
        let bonusCode: String
        let category: String
        let name: String
        let value: Int
        let city: String
        let state: String
        let flavor: String
        let imageData: String
    }

    // MARK: - Table view data source
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return jBonuses.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        // Table view cells are reused and should be dequeued using a cell identifier.
        let cellIdentifier = "BonusTableViewCell"

        guard let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as? BonusTableViewCell else {
            fatalError("The dequeued cell is not an instance of BonusTableViewCell.")
        }
    // Now using JSON file
        let jBonus = jBonuses[indexPath.row]
        print("Setting labels using JSON file")
        cell.bonusCodeLabel.text = jBonus.bonusCode
        cell.categoryLabel.text = jBonus.category
        cell.nameLabel.text = jBonus.name
        cell.valueLabel.text = "\(jBonus.value)"
        cell.cityLabel.text = "\(jBonus.city),"
        cell.stateLabel.text = jBonus.state
        cell.flavorText.text = jBonus.flavor
        cell.primaryImage.image = jBonus.photo

        return cell
    }

从控制台,我可以确认它能够看到 JSON 数据并且它确实吐出奖励代码列表。我无法确定为什么这不起作用,但结果是一个空白,只是一个带有一堆空行的表格视图。

viewDidLoad替换为

override func viewDidLoad() {
    super.viewDidLoad()

    jBonuses = loadJson(filename: "BonusData")!
    tableView.reloadData()
}

您必须将加载的数据分配给数据源数组并重新加载 table 视图。

或者如果 loadedBonuses 真的可以是 nil(在这种情况下不能):

override func viewDidLoad() {
    super.viewDidLoad()

    if let loadedBonuses = loadJson(filename: "BonusData") {
        jBonuses = loadedBonuses
        tableView.reloadData()
    }
}

备注:

  • 删除方法numberOfSections,默认1
  • 强制打开单元格,如果一切都正确连接,代码不能崩溃

    let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! BonusTableViewCell
    

您正在使用类型奖金的 jBonuses 数组填充 Tableview,但您在其中填充 jBonuses 数组。

您似乎没有填充 jBonuses 数组。获得 API 响应并调用 tableview reloadData 方法后填充 jBonuses 数组。

yourTableView.reloadData()