如何使用从服务器接收到的 JSON 数据更新 UI?
How can I update UI using JSON data that I'm receiving from the server?
我正在使用 Swift Codable Protocol 并接收 JSON 我需要放入我的标签和图像中的数据,但是当我 运行 应用程序。
这是我的代码的样子
import UIKit
struct OfferList: Codable {
let data: [Int: CarItems]?
let status: String?
let count: Int? }
struct CarItems: Codable {
let id: String?
let image: URL?
let manufacturer: String?
let model: String?
let price_net: Int?
let price_old: Int?
let price_gross: Int?
let power_kw: String?
let power_ps: String?
let milage: String?
let fueltype: String? }
class OfferVC: UIViewController {
@IBOutlet weak var tableView: UITableView!
var viewModels = [CarItems]() {
didSet {
self.tableView.reloadData()
}
}
override func viewDidLoad() {
super.viewDidLoad()
let urlString = "http://grandex.de/api/v1/de/offers"
guard let url = URL(string: urlString) else { return }
URLSession.shared.dataTask(with: url) { (data, response, err) in
guard let data = data else { return }
guard err == nil else { return }
do {
let array: Any = try JSONSerialization.jsonObject(with: data, options: [.allowFragments])
print(array)
if let objects = try JSONDecoder().decode(OfferList.self, from: data).data {
objects.forEach({
print([=12=])
self.viewModels.append()
DispatchQueue.main.async {
self.tableView.reloadData()
}
})
}
} catch let jsonErr {
print(jsonErr)
}
}.resume()
} }
extension OfferVC: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return viewModels.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "id") as! Cell
let vm = viewModels[indexPath.row]
cell.update(with: vm)
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 130
} }
class Cell: UITableViewCell {
@IBOutlet weak var carImage: UIImageView?
@IBOutlet weak var title: UILabel?
@IBOutlet weak var fuelType: UILabel?
func update(with item: CarItems) {
title?.text = item.manufacturer
fuelType?.text = item.fueltype
} }
我希望它能更改我的标签,但在模拟器中 table 视图是空的。
请指教我做错了什么。
还有人可以告诉我如何使用 JSON 数据更新图像吗?
任何帮助将非常感激!提前致谢!!
您需要在 viewDid load 中添加以下代码行。
tableView.dataSource = self
tableView.delegate = self
希望对您有所帮助。
结构中有两个主要错误,data
是 [CarItems]
和 priceNet
是 Double
。
你必须得到错误
Type 'Dictionary' mismatch: Expected to decode Dictionary but found an array instead.
声明所有结构成员 non-optional 并将它们命名为 camelCased
struct OfferList: Decodable {
let data: [CarItems]
let status: String
let count: Int
}
struct CarItems: Decodable {
let id: String
let image: URL
let manufacturer: String
let model: String
let priceNet: Double
let priceOld: Int
let priceGross: Int
let powerKw: String
let powerPs: String
let milage: String
let fueltype: String
}
声明没有属性观察者的数据源数组
var viewModels = [CarItems]()
解码JSON
URLSession.shared.dataTask(with: url) { (data, _, error) in
if let error = error { print(error); return }
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let result = try decoder.decode(OfferList.self, from: data!)
self.viewModels = result.data
DispatchQueue.main.async {
self.tableView.reloadData()
}
} catch {
print(error)
}
}.resume()
确保表视图的 datasource
和 delegate
已连接到 Interface Builder 中首选的视图控制器。
在 table 视图数据源和委托函数中添加断点,以确保有来自服务器的预期数据。另外,我看到在您的 CustomCell 中,插座属于可选类型,但不应该是。另外检查 update(with item: CarItems)
函数以使用断点查看标签和预期值是否存在。
我正在使用 Swift Codable Protocol 并接收 JSON 我需要放入我的标签和图像中的数据,但是当我 运行 应用程序。
这是我的代码的样子
import UIKit
struct OfferList: Codable {
let data: [Int: CarItems]?
let status: String?
let count: Int? }
struct CarItems: Codable {
let id: String?
let image: URL?
let manufacturer: String?
let model: String?
let price_net: Int?
let price_old: Int?
let price_gross: Int?
let power_kw: String?
let power_ps: String?
let milage: String?
let fueltype: String? }
class OfferVC: UIViewController {
@IBOutlet weak var tableView: UITableView!
var viewModels = [CarItems]() {
didSet {
self.tableView.reloadData()
}
}
override func viewDidLoad() {
super.viewDidLoad()
let urlString = "http://grandex.de/api/v1/de/offers"
guard let url = URL(string: urlString) else { return }
URLSession.shared.dataTask(with: url) { (data, response, err) in
guard let data = data else { return }
guard err == nil else { return }
do {
let array: Any = try JSONSerialization.jsonObject(with: data, options: [.allowFragments])
print(array)
if let objects = try JSONDecoder().decode(OfferList.self, from: data).data {
objects.forEach({
print([=12=])
self.viewModels.append()
DispatchQueue.main.async {
self.tableView.reloadData()
}
})
}
} catch let jsonErr {
print(jsonErr)
}
}.resume()
} }
extension OfferVC: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return viewModels.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "id") as! Cell
let vm = viewModels[indexPath.row]
cell.update(with: vm)
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 130
} }
class Cell: UITableViewCell {
@IBOutlet weak var carImage: UIImageView?
@IBOutlet weak var title: UILabel?
@IBOutlet weak var fuelType: UILabel?
func update(with item: CarItems) {
title?.text = item.manufacturer
fuelType?.text = item.fueltype
} }
我希望它能更改我的标签,但在模拟器中 table 视图是空的。 请指教我做错了什么。 还有人可以告诉我如何使用 JSON 数据更新图像吗? 任何帮助将非常感激!提前致谢!!
您需要在 viewDid load 中添加以下代码行。
tableView.dataSource = self
tableView.delegate = self
希望对您有所帮助。
结构中有两个主要错误,data
是 [CarItems]
和 priceNet
是 Double
。
你必须得到错误
Type 'Dictionary' mismatch: Expected to decode Dictionary but found an array instead.
声明所有结构成员 non-optional 并将它们命名为 camelCased
struct OfferList: Decodable {
let data: [CarItems]
let status: String
let count: Int
}
struct CarItems: Decodable {
let id: String
let image: URL
let manufacturer: String
let model: String
let priceNet: Double
let priceOld: Int
let priceGross: Int
let powerKw: String
let powerPs: String
let milage: String
let fueltype: String
}
声明没有属性观察者的数据源数组
var viewModels = [CarItems]()
解码JSON
URLSession.shared.dataTask(with: url) { (data, _, error) in
if let error = error { print(error); return }
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let result = try decoder.decode(OfferList.self, from: data!)
self.viewModels = result.data
DispatchQueue.main.async {
self.tableView.reloadData()
}
} catch {
print(error)
}
}.resume()
确保表视图的 datasource
和 delegate
已连接到 Interface Builder 中首选的视图控制器。
在 table 视图数据源和委托函数中添加断点,以确保有来自服务器的预期数据。另外,我看到在您的 CustomCell 中,插座属于可选类型,但不应该是。另外检查 update(with item: CarItems)
函数以使用断点查看标签和预期值是否存在。