// // SelectedShowVC.swift // MovieDataBase // // Created by BlumonPay on 3/1/21. // import UIKit import Darwin var storedOffsets = [Int: CGFloat]() let model = generateRandomData() class SelectedShowVC: UIViewController { // MARK: - Controller's properties let UI: SelectedShowView let coordinator: MainCoordinator let defaults: DefaultsManager private var factory: SelectedShowFactory lazy var viewModel: SelectedShowViewModelProtocol = { factory.makeSelectedShowViewModel(self, repository: factory.makeSelectedShowRepository()) }() // MARK: - Controller's initializers required init(UI: SelectedShowView, factory: SelectedShowFactory, coordinator: MainCoordinator, defaults: DefaultsManager) { self.UI = UI self.factory = factory self.coordinator = coordinator self.defaults = defaults super.init(nibName: nil, bundle: nil) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } // MARK: - Controller's life cycle override func loadView() { self.view = self.UI UI.delegate = self } override func viewDidLayoutSubviews() { setDelegates() } override func viewDidLoad() { super.viewDidLoad() self.navigationController?.isNavigationBarHidden = true } override func viewWillAppear(_ animated: Bool) { arrayCast.removeAll() arrayCreator.removeAll() arrayAiringSeason.removeAll() arrayOfSeasonsInt.removeAll() arrayCreatorName.removeAll() arraySeasonsEpisodes.removeAll() arregloDeArreglos.removeAll() arraySeasonsEpisodes.removeAll() arraySeasonsEpisodes2.removeAll() arraySeasonsEpisodes3.removeAll() arraySeasonsEpisodes4.removeAll() arraySeasonsEpisodes5.removeAll() arraySeasonsEpisodes6.removeAll() arraySeasonsEpisodes7.removeAll() arraySeasonsEpisodes8.removeAll() arraySeasonsEpisodes9.removeAll() arraySeasonsEpisodes10.removeAll() DispatchQueue.main.async { [self] in self.UI.posterHeader.image = UIImage() let urlImage = self.UI.SelectedBackdropp let imagenn = "https://image.tmdb.org/t/p/w500\(urlImage)" self.UI.posterHeader.downloaded(from: imagenn, contentMode: .scaleToFill) coordinator.showLoader() } DispatchQueue.main.async { [self] in getCastInfo(url: "https://api.themoviedb.org/3/tv/\(UI.SelectedIDD)/credits?api_key=8d9ced07152c868de3f180fef43510a7&language=en-US") } DispatchQueue.main.async { [self] in getCreators(url: "https://api.themoviedb.org/3/tv/\(UI.SelectedIDD)?api_key=8d9ced07152c868de3f180fef43510a7&language=en-US") } UI.tvTitleLabel.text = UI.SelectedNamee UI.descriptionTV.text = UI.SelectedOverVieww UI.scoreLabel.text = UI.SelectedVotee } override func viewDidAppear(_ animated: Bool) {} override func viewWillDisappear(_ animated: Bool) { } override func viewDidDisappear(_ animated: Bool) {} override func didReceiveMemoryWarning() { debugPrint("Memory warning!") } private func setDelegates() { UI.castCollectionView.delegate = self UI.castCollectionView.dataSource = self UI.tableSeasons.delegate = self UI.tableSeasons.dataSource = self } } extension SelectedShowVC: SelectedShowViewProtocol { } extension SelectedShowVC: SelectedShowViewDelegate { func dimiz(_ view: SelectedShowView) { self.navigationController?.popViewController(animated: true) } func popularBTN(_ view: SelectedShowView) { print("popular") } } extension SelectedShowVC: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { if collectionView == UI.castCollectionView{ return arrayCast.count }else{ return arraySeasonsEpisodes.count } } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { if collectionView == UI.castCollectionView{ let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "identifierCast", for: indexPath) as! CastCell cell.backgroundColor = .clear cell.model = arrayCast[indexPath.item] return cell }else{ let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "identifierSeasons", for: indexPath) as! SeasonCell cell.backgroundColor = .clear //global variable assign to the model for uicollectionview individual cell let arreglo = modelOfSeason[indexPath.item] cell.model = arreglo return cell } } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { if collectionView == UI.castCollectionView{ return CGSize(width: 180, height: 200) }else{ return CGSize(width: 180, height: 200) } } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { if collectionView == UI.castCollectionView{ return 30 }else{ return 30 } } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { if collectionView == UI.castCollectionView{ print("Collection view at row \(collectionView.tag) selected index path \(indexPath)") }else{ print("Collection view at row \(collectionView.tag) selected index path \(indexPath)") } } } extension SelectedShowVC{ func getCastInfo(url: String){ var semaphore = DispatchSemaphore (value: 0) var request = URLRequest(url: URL(string: url)!,timeoutInterval: Double.infinity) request.httpMethod = "GET" let task = URLSession.shared.dataTask(with: request) { data, response, error in guard let data = data else { print(String(describing: error)) self.coordinator.hideLoader(nil) semaphore.signal() return } semaphore.signal() do { let json = try JSONSerialization.jsonObject(with: data) if let jsonArray = json as? [[String:Any]] { // print("json is array", jsonArray) } else if let jsonDictionary = json as? NSDictionary { let toneCategories = jsonDictionary["cast"] as? [NSDictionary] ?? [] for category in toneCategories { let show = castt(dictionary: category) arrayCast.append(show) } DispatchQueue.main.async { self.UI.castCollectionView.reloadData() } } else { print("This should never be displayed") } } catch let error as NSError { self.coordinator.hideLoader(nil) print(error.localizedDescription) } } task.resume() semaphore.wait() } func getCreators(url: String){ var semaphore = DispatchSemaphore (value: 0) var request = URLRequest(url: URL(string: url)!,timeoutInterval: Double.infinity) request.httpMethod = "GET" let task = URLSession.shared.dataTask(with: request) { data, response, error in guard let data = data else { print(String(describing: error)) self.coordinator.hideLoader(nil) semaphore.signal() return } semaphore.signal() do { let json = try JSONSerialization.jsonObject(with: data) if let jsonArray = json as? [[String:Any]] { //print("json is array", jsonArray) } else if let jsonDictionary = json as? NSDictionary { //print("json is dictionary", jsonDictionary) let toneCategories = jsonDictionary["created_by"] as? [NSDictionary] ?? [] let toneCategories2 = jsonDictionary["last_episode_to_air"] as? NSDictionary ?? nil let season_numberr = toneCategories2?["season_number"] as? Int let still_pathh = toneCategories2?["still_path"] as? String let air_datee = toneCategories2?["air_date"] as? String season_number = String(season_numberr ?? 0) still_path = still_pathh ?? "" air_date = air_datee ?? "" for category in toneCategories { let show = created(dictionary: category) arrayCreator.append(show) let descrp = category["name"] arrayCreatorName.append(descrp as? String ?? "") } DispatchQueue.main.async { let number = Int(season_number) ?? 0 let reversedCollection = (1 ... number).reversed() for index in reversedCollection { //arreglo para las temporadas arrayOfSeasonsInt.append(index) } let urlImage = still_path let imagenn = "https://image.tmdb.org/t/p/w500\(urlImage)" self.UI.posterLastSeason.downloaded(from: imagenn, contentMode: .scaleToFill) self.UI.seasonNumber.text = "Season \(season_number)" self.UI.lastDateSeason.text = air_date let formatter = ListFormatter() if let string = formatter.string(from: arrayCreatorName) { self.UI.creatorLabel.text = "Created by: \(string)" } //self.coordinator.hideLoader(nil) } DispatchQueue.main.async { [self] in let arregloparaSeasons = arrayOfSeasonsInt.count for index in 1...arregloparaSeasons { getSeasons(url: "https://api.themoviedb.org/3/tv/\(UI.SelectedIDD)/season/\(index)?api_key=8d9ced07152c868de3f180fef43510a7&language=en-US") } self.coordinator.hideLoader(nil) } } else { print("This should never be displayed") } } catch let error as NSError { self.coordinator.hideLoader(nil) print(error.localizedDescription) } } task.resume() semaphore.wait() } func getSeasons(url: String){ var semaphore = DispatchSemaphore (value: 0) var request = URLRequest(url: URL(string: url)!,timeoutInterval: Double.infinity) request.httpMethod = "GET" let task = URLSession.shared.dataTask(with: request) { data, response, error in guard let data = data else { print(String(describing: error)) self.coordinator.hideLoader(nil) semaphore.signal() return } semaphore.signal() do { let json = try JSONSerialization.jsonObject(with: data) if json is [[String:Any]] { // print("json is array", jsonArray) } else if let jsonDictionary = json as? NSDictionary { let toneCategories = jsonDictionary["episodes"] as? [NSDictionary] ?? [] let season = jsonDictionary["season_number"] as? Int ?? 0 for category in toneCategories { if season == 1{ let show = episodess(dictionary: category, seasonInt: season) arraySeasonsEpisodes.append(show) }else if season == 2{ let show = episodess(dictionary: category, seasonInt: season) arraySeasonsEpisodes2.append(show) } if season == 3{ let show = episodess(dictionary: category, seasonInt: season) arraySeasonsEpisodes3.append(show) }else if season == 4{ let show = episodess(dictionary: category, seasonInt: season) arraySeasonsEpisodes4.append(show) } if season == 5{ let show = episodess(dictionary: category, seasonInt: season) arraySeasonsEpisodes5.append(show) }else if season == 6{ let show = episodess(dictionary: category, seasonInt: season) arraySeasonsEpisodes6.append(show) } if season == 7{ let show = episodess(dictionary: category, seasonInt: season) arraySeasonsEpisodes7.append(show) }else if season == 8{ let show = episodess(dictionary: category, seasonInt: season) arraySeasonsEpisodes8.append(show) } if season == 9{ let show = episodess(dictionary: category, seasonInt: season) arraySeasonsEpisodes9.append(show) }else if season == 10{ let show = episodess(dictionary: category, seasonInt: season) arraySeasonsEpisodes10.append(show) } } DispatchQueue.main.async { self.UI.tableSeasons.reloadData() self.coordinator.hideLoader(nil) } } else { print("This should never be displayed") } } catch let error as NSError { self.coordinator.hideLoader(nil) print(error.localizedDescription) } } task.resume() semaphore.wait() } } extension SelectedShowVC: UITableViewDelegate, UITableViewDataSource { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return arrayOfSeasonsInt.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { guard let cell = tableView.dequeueReusableCell(withIdentifier: "seasonsRegister", for: indexPath) as? NumberOfSeasonsCell else { return UITableViewCell() } cell.selectionStyle = .none cell.backgroundColor = .clear //note for each cell i manually asign an different array if indexPath.row == 0 { let arreglo = arraySeasonsEpisodes //array which contains all the information from the first season modelOfSeason = arreglo // to a global variable i asign the content the of adove season let arregloDeArregloss = arregloBidimencional(arreglo: arreglo, tag: 0) // this is for saving the adove array (the season) to another array arregloDeArreglos.append([arregloDeArregloss]) } else if indexPath.row == 1{ let arreglo = arraySeasonsEpisodes2 //array which contains all the information from the second season modelOfSeason = arreglo // to a global variable i asign the content the of adove season let arregloDeArregloss = arregloBidimencional(arreglo: arreglo, tag: 1)// this is for saving the adove array (the season) to another array arregloDeArreglos.append([arregloDeArregloss]) } else if indexPath.row == 2{ let arreglo = arraySeasonsEpisodes3 modelOfSeason = arreglo let arregloDeArregloss = arregloBidimencional(arreglo: arreglo, tag: 2) arregloDeArreglos.append([arregloDeArregloss]) } else if indexPath.row == 3{ let arreglo = arraySeasonsEpisodes4 modelOfSeason = arreglo let arregloDeArregloss = arregloBidimencional(arreglo: arreglo, tag: 3) arregloDeArreglos.append([arregloDeArregloss]) } else if indexPath.row == 4{ let arreglo = arraySeasonsEpisodes5 modelOfSeason = arreglo let arregloDeArregloss = arregloBidimencional(arreglo: arreglo, tag: 4) arregloDeArreglos.append([arregloDeArregloss]) } else if indexPath.row == 5{ let arreglo = arraySeasonsEpisodes6 modelOfSeason = arreglo let arregloDeArregloss = arregloBidimencional(arreglo: arreglo, tag: 5) arregloDeArreglos.append([arregloDeArregloss]) } else if indexPath.row == 6{ let arreglo = arraySeasonsEpisodes7 modelOfSeason = arreglo let arregloDeArregloss = arregloBidimencional(arreglo: arreglo, tag: 6) arregloDeArreglos.append([arregloDeArregloss]) } else if indexPath.row == 7{ let arreglo = arraySeasonsEpisodes8 modelOfSeason = arreglo let arregloDeArregloss = arregloBidimencional(arreglo: arreglo, tag: 7) arregloDeArreglos.append([arregloDeArregloss]) } else if indexPath.row == 8{ let arreglo = arraySeasonsEpisodes9 modelOfSeason = arreglo let arregloDeArregloss = arregloBidimencional(arreglo: arreglo, tag: 8) arregloDeArreglos.append([arregloDeArregloss]) } else if indexPath.row == 9{ let arreglo = arraySeasonsEpisodes10 modelOfSeason = arreglo let arregloDeArregloss = arregloBidimencional(arreglo: arreglo, tag: 9) arregloDeArreglos.append([arregloDeArregloss]) } else{ } return cell } func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 200 } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { print(indexPath.row) } func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { guard let tableViewCell = cell as? NumberOfSeasonsCell else { return } //this method is for saving the offset and delegate for each cell tableViewCell.setCollectionViewDataSourceDelegate(self, forRow: indexPath.row) tableViewCell.collectionViewOffset = storedOffsets[indexPath.row] ?? 0 } func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) { //this method is for saving the offset and delegate for each cell guard let tableViewCell = cell as? NumberOfSeasonsCell else { return } storedOffsets[indexPath.row] = tableViewCell.collectionViewOffset } }