Reputation: 185
I need to show info about movies(taken from https://developers.themoviedb.org/) in tableView. I'm doing network request using a singleton and then pass parsed data to tableViewController through completion handler. I can print received data but I can't properly set them in tableView cell. Could you please help me how to fix this problem.
Network Manager
func getMovies(completion: @escaping ([Movies]?) -> Void) {
guard let url = URL(string: "https://api.themoviedb.org/3/movie/now_playing?api_key=\(apiKey)&language=en")
else { fatalError("Wrong URL") }
URLSession.shared.dataTask(with: url) { (data, response, error) in
if let jsonData = data {
let decoder = JSONDecoder()
do {
let moviesResult = try decoder.decode(MoviesResult.self, from: jsonData)
let movies = moviesResult.results
completion(movies)
}
catch {
print(error)
}
}
}.resume()
}
Movies View Controller
var movies = [Movies]()
override func viewDidLoad() {
super.viewDidLoad()
network.getMovies { result in
if let result = result {
self.movies = result
print(self.movies)
}
}
extension MoviesViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return movies.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let movie = movies[indexPath.row]
print(movie)
if let cell = tableView.dequeueReusableCell(withIdentifier: "moviesMainInfo", for: indexPath) as? MovieTableViewCell {
cell.filmTitle.text = movie.title
cell.filmRating.text = String(movie.popularity!)
return cell
}
return UITableViewCell()
}
}
Parsed result: [MovieApp.Movies(genreIDs: Optional([14, 28, 12]), overview: Optional("Wonder Woman comes into conflict with the Soviet Union during the Cold War in the 1980s and finds a formidable foe by the name of the Cheetah."), popularity: Optional(1927.057), title: Optional("Wonder Woman 1984"), releaseDate: Optional("2020-12-16"), posterPath: Optional("/8UlWHLMpgZm9bx6QYh0NFoq67TZ.jpg")),
Upvotes: 0
Views: 108
Reputation: 2217
You are doing everything correctly, you just need to reload your UITableView
when data arrives. Be aware that you need to reload your UITableView
on the main thread, because UIKit
isn't thread safe:
otherwise your application will most probably crash:
private func reloadTableView() {
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
Also I encourage you to extract your networking function from viewDidLoad
. An other improvement is to use [weak self]
in your closures to avoid memory leaks:
private func loadData() {
network.getMovies { [weak self] result in
if let result = result {
self?.movies = result
print(self?.movies)
self?.reloadTableView()
} else {
// Maybe show some info that the data could not be fetched
}
}
}
And in your viewDidLoad
just call it:
override func viewDidLoad() {
super.viewDidLoad()
loadData()
}
Upvotes: 1