Как уже упоминалось в комментариях к исходному сообщению, источником данных для вашего TableView должен быть ваш класс ViewController.
Вы можете извлекать продукты и предоставлять данные в отдельный класс ShopModel, но он не должен наследовать UIViewController.
Попробуйте что-то вроде этого:
import UIKit
struct Product: Codable {
var title: String
var price: Double
var isFeatured: Bool
}
class ShopViewController: UIViewController {
private var products = [Product]()
private var tableView: UITableView!
override func viewDidLoad() {
setupLayout()
fetchProducts()
}
private func setupLayout() {
tableView = UITableView()
view.addSubview(tableView)
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
tableView.dataSource = self
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "productCell")
}
private func fetchProducts() {
URLSession.shared.dataTask(with: URL(string: "192.168.1.1/products")!, completionHandler: { data, response, error in
guard error == nil else {
print(error!.localizedDescription)
return
}
do {
self.products = try JSONDecoder().decode([Product].self, from: data!)
// Refresh table after downloading products and make sure to do it from main thread
DispatchQueue.main.async {
self.tableView.reloadData()
}
} catch {
print("Error decoding list of products from received data.")
}
}).resume()
}
}
extension ShopViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
// Featured products
return products.filter { $0.isFeatured }.count
} else {
// All products
return products.count
}
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "productCell", for: indexPath)
cell.textLabel?.text = products[indexPath.row].title
cell.detailTextLabel?.text = String(products[indexPath.row].price)
return cell
}
}
Я немного упростил модель продукта и извлек ее из URL-адреса заполнителя, но я надеюсь, что вы поняли.