#ios #json #swift #xcode #uitableview
#iOS #json #быстрый #xcode #uitableview
Вопрос:
Я получаю данные json из api и совершенно не понимаю, что мне делать дальше, чтобы передать эти данные в пользовательскую ячейку с изображением и метками, чтобы обновить пользовательский интерфейс в TableView.
Получение JSON
import Foundation struct Breed: Codable { let name: String? let origin: String? let life_span:String? let temperament: String? let description: String? let wikipedia_url: String? let image: Image? } struct Image: Codable { let url: String? } func getDataFromCatsApi() { let url = URL(string: "https://api.thecatapi.com/v1/breeds") let task = URLSession.shared.dataTask(with: url!) { data, _ , error in let decoder = JSONDecoder() if let data = data { let breed = try? decoder.decode([Breed].self, from: data) print (breed as Any) } else { print (error as Any) } } task.resume() }
Все данные напечатаны правильно.
В ViewController у меня есть табличное представление с пользовательской ячейкой.
import UIKit class MainVC: UIViewController { @IBOutlet weak var tableView: UITableView! override func viewDidLoad() { super.viewDidLoad() title = "Cats" view.backgroundColor = .systemBackground getDataFromCatsApi() } } extension MainVC: UITableViewDelegate, UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -gt; Int { return 5 } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -gt; UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? CustomTableViewCell return cell ?? CustomTableViewCell() } }
Класс для пользовательской ячейки. Здесь у меня есть просмотр изображений и метки для отображения данных из json.
import UIKit class CustomTableViewCell: UITableViewCell { @IBOutlet weak var catImageView: UIImageView! @IBOutlet weak var nameLabel: UILabel! @IBOutlet weak var originLabel: UILabel! @IBOutlet weak var addToFavButton: UIButton! }
Ответ №1:
Во-первых, вы ничего не возвращаете getDataFromCatsApi().
, так как это асинхронный вызов, вы должны реализовать способ получения значений либо с помощью обратного вызова, либо делегата. В этом случае обратного вызова было бы достаточно.
Затем, как только вы получите значение из вызова api, установите те значения func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath)
, в которых вы можете использовать cell.nameLabel.text = lt;received valuegt;
и т. Д.
Ответ №2:
Прежде всего объявите необязательными только те свойства, которые могут быть nil
struct Breed: Decodable { let name, origin, lifeSpan, temperament, description: String let wikipediaUrl: String? let image: Image? } struct Image: Decodable { let url: String? }
В getDataFromCatsApi
поле добавить обработчик завершения
func getDataFromCatsApi(completion: @escaping (Resultlt;[Breed],Errorgt;) -gt; Void ) { let url = URL(string: "https://api.thecatapi.com/v1/breeds") let task = URLSession.shared.dataTask(with: url!) { data, _ , error in if let error = error { completion(.failure(error)); return } let decoder = JSONDecoder() decoder.keyDecodingStrategy = .convertFromSnakeCase completion(Result { try decoder.decode([Breed].self, from: data!) }) } task.resume() }
В MainVC
объявлении массива источников данных
var cats = [Breed]()
Заменить viewDidLoad
на
override func viewDidLoad() { super.viewDidLoad() title = "Cats" view.backgroundColor = .systemBackground getDataFromCatsApi {[unowned self] result in DispatchQueue.main.async { switch result { case .success(let breed): self.cats = breed self.tableView.reloadData() case .failure(let error): print(error) } } } }
и методы источников данных табличного представления с
extension MainVC: UITableViewDelegate, UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -gt; Int { return cats.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -gt; UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! CustomTableViewCell let cat = cats[indexPath.row] cell.nameLabel = cat.name cell.originLabel = cat.origin } }
Загрузка изображений выходит за рамки вопроса. Существуют библиотеки, такие как SDWebImage или Kingfisher, для асинхронной загрузки и кэширования изображений.
Ответ №3:
Я прикрепил код, пожалуйста, проверьте
extension MainVC: UITableViewDelegate, UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -gt; Int { return Breed.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -gt; UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as? CustomTableViewCell cell.nameLabel.text = Breed[indexPath.row].name // see here return cell ?? CustomTableViewCell() } }
Комментарии:
1. У меня сбой из-за нуля, найденного в » var Breed: [Порода]!»