前回の質問からの進展
前回思うように結果を受け取れたので
1.queryを入れ複数の情報に対応させました。
2.TextFieldを追加してTableViewで検索機能を追加。
3.TableViewCellを作成しnibに表示したい項目を追加。
4.新たにidをAPiから取得してdidselectを追加。
ソースコード
ViewController
1import UIKit 2import SafariServices 3 4class ViewController: UIViewController,UITextFieldDelegate { 5 6 @IBOutlet weak var movieTableView: UITableView! 7 @IBOutlet weak var field: UITextField! 8 9 var movies = [Movie]() 10 11 override func viewDidLoad() { 12 super.viewDidLoad() 13 movieTableView.register(MovieTableViewCell.nib(), forCellReuseIdentifier: MovieTableViewCell.identifier) 14 15 movieTableView.delegate = self 16 movieTableView.dataSource = self 17 field.delegate = self 18 19 fechData() 20 } 21 22 func textFieldShouldReturn(_ textField: UITextField) -> Bool { 23 fechData() 24 return true 25 } 26 27 func fechData(){ 28 29 field.resignFirstResponder() 30 31 guard let text = field.text, !text.isEmpty else { 32 return 33 } 34 35 let query = text.replacingOccurrences(of: " ", with: "%20") 36 let url = text.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) 37 38 movies.removeAll() 39 40 URLSession.shared.dataTask(with: URL(string: "https://api.themoviedb.org/3/search/movie?api_key=自分のAPI&language=ja&query=(query)&page=1")!, 41 completionHandler: {data, response, error in 42 43 guard let data = data else { 44 print(error?.localizedDescription ?? "Unknown error") 45 return 46 } 47 48 var result: MovieStruct? 49 do { 50 result = try JSONDecoder().decode(MovieStruct.self, from: data) 51 } 52 catch{ 53 print("JSON perse error") 54 } 55 56 guard let finalResult = result else{ 57 return 58 } 59 60 let newMovies = finalResult.results 61 self.movies.append(contentsOf: newMovies) 62 63 DispatchQueue.main.async { 64 self.movieTableView.reloadData() 65 } 66 }).resume() 67 } 68} 69 70extension ViewController:UITableViewDelegate,UITableViewDataSource{ 71 72 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 73 return movies.count 74 } 75 76 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 77 let cell = movieTableView.dequeueReusableCell(withIdentifier: MovieTableViewCell.identifier, for: indexPath) as! MovieTableViewCell 78 cell.configure(with: movies[indexPath.row]) 79 return cell 80 } 81 82 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 83 tableView.deselectRow(at: indexPath, animated: true) 84 let url = "https://www.themoviedb.org/movie/(movies[indexPath.row].id)?language=ja" 85 let vc = SFSafariViewController(url: URL(string: url)!) 86 present(vc, animated: true) 87 } 88} 89 90struct MovieStruct:Codable { 91 let results: [Movie] 92} 93 94struct Movie: Codable { 95 let title: String 96 let release_date:String? 97 let poster_path:String? 98 let id:Int? 99}
TableViewCell
MovieTableViewCell
1import UIKit 2 3class MovieTableViewCell: UITableViewCell { 4 5 @IBOutlet var movieTitleLabel: UILabel! 6 @IBOutlet var movieReleaseDateLabel: UILabel! 7 @IBOutlet var moviePosterImageView: UIImageView! 8 9 override func awakeFromNib() { 10 super.awakeFromNib() 11 // Initialization code 12 } 13 14 override func setSelected(_ selected: Bool, animated: Bool) { 15 super.setSelected(selected, animated: animated) 16 17 } 18 19 static let identifier = "MovieTableViewCell" 20 21 static func nib() -> UINib{ 22 return UINib(nibName: "MovieTableViewCell", bundle: nil) 23 } 24 25 func configure(with model:Movie){ 26 self.movieTitleLabel.text = model.title 27 self.movieReleaseDateLabel.text = model.release_date 28 let url = model.poster_path 29 if let data = try? Data(contentsOf: URL(string: url!)!){ 30 self.moviePosterImageView.image = UIImage(data: data) 31 } 32 } 33} 34
不明点&エラー
1.検索Hitにばらつきがあり、urlにnillが入ってしまう。
例えばstarと入力するとSTARWARSの情報が出るのですが
titanicと入力するとconfigureのところで
Fatal error: Unexpectedly found nil while unwrapping an Optional value
となりurlにnillが入っています。
2.posterが表示されない
上記の検索Hitした、していないにかかわらず
Hitした場合MovieTableViewCellで設定したmoviePosterImageViewが何も表示されずに真っ白です。
titleとrelease_dateは表示されるのでposter_pathのみ受け取れていないのかどこかでnilを設定してしまわれているのだと思います。
3.日本語対応ができない
以前APIの日本語を受け取るためには
let url = text.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)
で日本語対応できると習ったのですがURLSessionのところで
Fatal error: Unexpectedly found nil while unwrapping an Optional value
と出てしまいます。
4.didselectで思うようなサイトに飛べない。
let url = "https://www.themoviedb.org/movie/(movies[indexPath.row].id)?language=ja" let vc = SFSafariViewController(url: URL(string: url)!) present(vc, animated: true)
このようにIMDBの映画情報詳細ページに飛びたいのですが
IMDBのHPサイトには飛ぶのですが探しているページは見つかりませんと出ます。
STARWARS 最後のジェダイの詳細URL https://www.themoviedb.org/movie/181808-star-wars-the-last-jedi?language=ja ドラえもん 宝島 //https://www.themoviedb.org/movie/495925?language=ja
上記のように検索URLにばらつきがあるので
let url = "https://www.themoviedb.org/movie/(movies[indexPath.row].id)?language=ja"
上記だとidのみを設定しているのでTitileも考慮して設定しなければなりませんか?
質問、コード等が多くなってしまい大変申し訳ありません。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/31 13:22