从 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()
我正在尝试使用 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()