Заполнение UITableView из JSON - PullRequest
       8

Заполнение UITableView из JSON

0 голосов
/ 30 апреля 2018

Я пытаюсь использовать файл 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 и выдает список бонусных кодов. Я не могу точно определить, почему это не работает, но в результате получается пустой вид таблицы с кучей пустых строк.

Ответы [ 2 ]

0 голосов
/ 30 апреля 2018

Вы заполняете Tableview с помощью массива jBonuses типа Бонусы, но там, где вы заполняете массив jBonuses.

Кажется, вы не заполняете массив jBonuses. Заполните массив jBonuses, как только вы получите ответ API и вызовете метод reloadData таблицы view.

yourTableView.reloadData()
0 голосов
/ 30 апреля 2018

Заменить viewDidLoad на

override func viewDidLoad() {
    super.viewDidLoad()

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

Вы должны назначить загруженные данные в массив источника данных и перезагрузить табличное представление.

Или, если 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
    
...