Передача данных из Api в массив для отображения на экране


#1

Суть такая, есть менеджер для парса данных

protocol NetworkDataManagerDelegate: AnyObject {
    func updateInterface( _: NetworkDataManager, with currenData: CurrentData)
}

class NetworkDataManager {
    weak var delegate: NetworkDataManagerDelegate?
    func fetchCurrentData() {
        let urlString = "https://run.mocky.io/v3/1d1cb4ec-73db-4762-8c4b-0b8aa3cecd4c"
        guard let url = URL(string: urlString) else {return}
        let urlSession = URLSession(configuration: .default)
        let task = urlSession.dataTask(with: url) { data, responce, error in
            if let data = data {
                if let currentData = self.parseJSON(withData: data){
                    self.delegate?.updateInterface(self, with: currentData)
                }
            }
        }
        
        task.resume()
    }
    
    func parseJSON(withData data: Data) -> CurrentData?{
        
        let decoder = JSONDecoder()
        do {
            let currentDataData = try decoder.decode(CurrentDataData.self, from: data)
            guard let currentData = CurrentData(currentDataData: currentDataData) else {return nil}
            return currentData
        } catch let error as NSError {
            print(error)
        }
        return nil
    }
    
}

На tableViewController предаю через протокол в котором есть класс updateInterface(), вопрос такой, как передать данные в массив cell, что бы подтягивалось нужно кол-во ячеек? У ячеек есть отдельный viewController на который они собственно и подключены.
view для ячеек

    import UIKit

class CustomCell: UITableViewCell {

    @IBOutlet weak var skilsLable: UILabel!
    @IBOutlet weak var numbeLable: UILabel!
    @IBOutlet weak var nameLable: UILabel!
    
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

}

Вот и сам tableViewController

 class MyTableViewController: UITableViewController {

    var cell: [String] = []
    let network = NetworkDataManager()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        network.fetchCurrentData()
        network.delegate = self

        tableView.rowHeight = 150
        self.title = "Team of Developer"
    }

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return cell.count
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomCell
        return cell
    }
}


extension MyTableViewController: NetworkDataManagerDelegate{
    func updateInterface(_: NetworkDataManager, with currenData: CurrentData) {
        
    }
    
    
}


#2

По вопросу вашему, вам нужно в методе делегата установить параметр :

после этого сделать reload таблицы
не забыть про установку проверти ячейки тут:

Но я бы вам предложил пересмотреть решение, я накидал немного кода, может вам будет полезно посмотреть, если нет то забейте)

// MARK: - NETWORK -

// MARK: - NetworkLoader

protocol Cancelable {
    func cancel()
}

extension URLSessionDataTask: Cancelable { }

// можно покрыть протколом
final class NetworkDataLoader {
    @discardableResult
    func fetch<T: Decodable>(
        urlRequest: URLRequest,
        decoder: JSONDecoder = JSONDecoder(),
        urlSession: URLSession = URLSession.shared,
        completionThread: DispatchQueue = .main,
        completion: @escaping (Result<T, Error>) -> Void
    ) -> Cancelable {
        let task = urlSession.dataTask(with: urlRequest) { data, resposnse, error in
            if let error = error {
                completionThread.async {
                    completion(.failure(error))
                }
            } else if let data = data {
                do {
                    let result = try decoder.decode(T.self, from: data)
                    completionThread.async {
                        completion(.success(result))
                    }
                } catch {
                    completionThread.async {
                        completion(.failure(error))
                    }
                }
            } else {
                completionThread.async {
//                    completion(.failure()) any custom error
                }
            }
        }
        task.resume()
        return task
    }
}

// MARK: - Company
struct Company: Codable {
    let name: String
    let employees: [Employee]
}

// MARK: - Employee
struct Employee: Codable {
    let name, phoneNumber: String
    let skills: [String]

    enum CodingKeys: String, CodingKey {
        case name
        case phoneNumber = "phone_number"
        case skills
    }
}

protocol CompanyNetworkService {
    @discardableResult
    func getComny(completion: @escaping (Result<Company, Error>) -> Void) -> Cancelable?
}

final class NetworkService: CompanyNetworkService {
    // стоит скармливать в зависимость не конкретный класс, мне лень писать, но из контекста понятно
    let loader: NetworkDataLoader
    
    init(loader: NetworkDataLoader = NetworkDataLoader()) {
        self.loader = loader
    }
    
    func getComny(completion: @escaping (Result<Company, Error>) -> Void) -> Cancelable? {
        guard let url = URL(string: "https://run.mocky.io/v3/1d1cb4ec-73db-4762-8c4b-0b8aa3cecd4c") else {
            completion(.failure(URLError(.badURL)))
            return nil
        }
        return loader.fetch(urlRequest: URLRequest(url: url), completion: completion)
    }
}

// MARK: - UI -

protocol ViewModelBindable {
    associatedtype ViewModel
    
    func bind(viewMode: ViewModel)
}

final class CustomCell: UITableViewCell, ViewModelBindable {
    typealias ViewModel = Employee
    
    @IBOutlet weak var skilsLable: UILabel!
    @IBOutlet weak var numbeLable: UILabel!
    @IBOutlet weak var nameLable: UILabel!
    
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }
    
    func bind(viewMode: Employee) {
        // any work
    }
}

class MyTableViewController: UITableViewController {
    typealias CellModel = Employee
    var dataSource: [CellModel] = []
    // это должно скармливаться извне ;)
    var networkService: CompanyNetworkService! = NetworkService()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        precondition(networkService != nil, "network service should be set before viewDidLoad")
        
        networkService.getComny { [weak self] result in
            switch result {
            case .success(let company):
                self?.dataSource = company.employees
                self?.tableView.reloadData()
                
            case .failure(let error):
                Logger().error("fetch companies error: \(error.localizedDescription)")
            }
        }
        
        tableView.rowHeight = 150
        self.title = "Team of Developer"
    }
    
    // MARK: - Table view data source
    
    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }
    
    override func tableView(
        _ tableView: UITableView,
        numberOfRowsInSection section: Int
    ) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return dataSource.count
    }
    
    override func tableView(
        _ tableView: UITableView,
        cellForRowAt indexPath: IndexPath
    ) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! CustomCell
        cell.bind(viewMode: dataSource[indexPath.row])
        return cell
    }
}