我在以表格视图显示JSON图像时遇到麻烦
我正在尝试显示来自API的图像.这些图像位于URL内,我想用所有数组填充一个表格视图",但是在表格视图"中仅显示一张图像.
I'm trying to display images that comes from an API. The images are inside an URL and I want to fill a Table View with all the array, but it shows only one image at the Table View.
这是我的代码:
struct Autos {
let Marca:String
let Modelo:String
let Precio:String
let RutaImagen:String
init?(_ dict:[String:Any]?){
guard let _dict = dict,
let marca=_dict["Marca"]as?String,
let modelo=_dict["Modelo"]as?String,
let precio=_dict["Precio"]as?String,
let rutaImagen=_dict["RutaImagen"]as?String
else { return nil }
self.Marca = marca
self.Modelo = modelo
self.Precio = precio
self.RutaImagen = rutaImagen
}
}
var arrAutos = [Autos]()
func getImage(from string: String) -> UIImage? {
// Get valid URL
guard let url = URL(string: string)
else {
print("Unable to create URL")
return nil
}
var image: UIImage? = nil
do {
// Get valid data
let data = try Data(contentsOf: url, options: [])
// Make image
image = UIImage(data: data)
}
catch {
print(error.localizedDescription)
}
return image
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 9
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "carsCell", for: indexPath) as! CarsDetailTableViewCell
let url = URL(string: "http://ws-smartit.divisionautomotriz.com/wsApiCasaTrust/api/autos")!
let task = URLSession.shared.dataTask(with: url) {
(data, response, error) in
guard let dataResponse = data, error == nil else {
print(error?.localizedDescription ?? "Response Error")
return
}
do {
let jsonResponse = try JSONSerialization.jsonObject(with: dataResponse, options: []) as? NSArray
self.arrAutos = jsonResponse!.compactMap({ Autos($0 as? [String:String])})
DispatchQueue.main.async {
// Get valid string
let string = self.arrAutos[indexPath.row].RutaImagen
if let image = self.getImage(from: string) {
// Apply image
cell.imgCar.image = image
}
cell.lblBrand.text = self.arrAutos[indexPath.row].Marca
cell.lblPrice.text = self.arrAutos[indexPath.row].Precio
cell.lblModel.text = self.arrAutos[indexPath.row].Modelo
}
} catch let parsingError {
print("Error", parsingError)
}
}
task.resume()
return cell
}
JSON序列化工作正常,因为其他数据在表视图中正确显示,问题出在图像上,因为在表视图中仅出现一个图像,其他行为空.有人有建议吗?
The JSON serialization is working fine, because the other data is showed correctly at the table view, the issue is with the image, because in the table view only appears one image, the other rows are empty. Does anyone have an advise?
我认为您应该先下载完整的数据,然后再加载tableview并在完成处理程序中重新加载tableview.在viewDidLoad()
中调用loadData()
方法.
I think you should download your full data before loading tableview and reload tableview in the completion handler. Call loadData()
method in your viewDidLoad()
.
fileprivate func loadData() {
let url = URL(string: "http://ws-smartit.divisionautomotriz.com/wsApiCasaTrust/api/autos")!
let task = URLSession.shared.dataTask(with: url) {
(data, response, error) in
guard let dataResponse = data, error == nil else {
print(error?.localizedDescription ?? "Response Error")
return
}
do {
let jsonResponse = try JSONSerialization.jsonObject(with: dataResponse, options: []) as? NSArray
self.arrAutos = jsonResponse!.compactMap({ Autos($0 as? [String:String])})
DispatchQueue.main.async {
self.tableView.reloadData()
}
} catch let parsingError {
print("Error", parsingError)
}
}
task.resume()
}
要在tableView单元格中加载图像,请在background
线程中下载图像,然后在main
线程中更新imageView.
For loading images in tableView cell, download the image in background
thread and then update the imageView in the main
thread.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "carsCell", for: indexPath) as! CarsDetailTableViewCell
// Get valid string
let string = self.arrAutos[indexPath.row].RutaImagen
//print(string)
cell.lblBrand.text = self.arrAutos[indexPath.row].Marca
cell.lblPrice.text = self.arrAutos[indexPath.row].Precio
cell.lblModel.text = self.arrAutos[indexPath.row].Modelo
let url = URL(string: string)
if url != nil {
DispatchQueue.global().async {
let data = try? Data(contentsOf: url!)
DispatchQueue.main.async {
if data != nil {
cell.imgCar.image = UIImage(data:data!)
}
}
}
}
return cell
}
希望这会起作用.