質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

1688閲覧

JSONをDecodeしてTableViewに表示したい

Ytan

総合スコア39

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2020/07/23 14:51

編集2020/07/25 13:01

実現したいこと

JSONをDecodeしてTableViewに表示したい
配列に格納して取り出したい

問題点

Swift5

1import UIKit 2 3class ViewController: UIViewController { 4//https://api.themoviedb.org/3/movie/550?api_key=b562d3142fef5c7d35279900383f0850 5 6 @IBOutlet weak var movieTableView: UITableView! 7 8 var movies = [MovieStruct]() 9 10 override func viewDidLoad() { 11 super.viewDidLoad() 12 // Do any additional setup after loading the view. 13 14 fechData() 15 } 16 17 func fechData(){ 18 19 let url = URL(string: "https://api.themoviedb.org/3/movie/550)! 20 URLSession.shared.dataTask(with: url) { (data, response, error) in 21 guard let data = data else { 22 print(error?.localizedDescription ?? "Unknown error") 23 return 24 } 25 26 let decoder = JSONDecoder() 27 28 if let movies = try? decoder.decode([MovieStruct].self, from: data){ 29 DispatchQueue.main.async { 30 self.movies = movies 31 self.movieTableView.reloadData() 32 } 33 }else{ 34 print("Unable parse JSON response") 35 } 36 }.resume() 37 } 38} 39 40extension ViewController:UITableViewDelegate,UITableViewDataSource{ 41 42 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 43 return movies.count 44 } 45 46 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 47 let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 48 let movie = movies[indexPath.row] 49 50 cell.textLabel?.text = movie.title 51 cell.textLabel?.text = movie.release_date 52 53 return cell 54 } 55} 56 57struct MovieStruct: Codable { 58 var title: String 59 var release_date:String 60} 61 62

上記のリクエスト方法でエラーなくビルドした結果

Unable parse JSON response

となったのですがなぜ上手く表示されないのですか?
ResponseのAPIは間違っておらず実際に受け取ると下記の結果となります。

また前の質問で載せたソースコードでは理解しずらかったのでこちらの通信の仕方にしました。

Response

{ adult = 0; "backdrop_path" = "/8iVyhmjzUbvAGppkdCZPiyEHSoF.jpg"; "belongs_to_collection" = "<null>"; budget = 63000000; genres = ( { id = 18; name = Drama; } ); homepage = "http://www.foxmovies.com/movies/fight-club"; id = 550; "imdb_id" = tt0137523; "original_language" = en; "original_title" = "Fight Club"; overview = "A ticking-time-bomb insomniac and a slippery soap salesman channel primal male aggression into a shocking new form of therapy. Their concept catches on, with underground \"fight clubs\" forming in every town, until an eccentric gets in the way and ignites an out-of-control spiral toward oblivion."; popularity = "39.218"; "poster_path" = "/wR5HZWdVpcXx9sevV1bQi7rP4op.jpg"; "production_companies" = ( { id = 508; "logo_path" = "/7PzJdsLGlR7oW4J0J5Xcd0pHGRg.png"; name = "Regency Enterprises"; "origin_country" = US; }, { id = 711; "logo_path" = "/tEiIH5QesdheJmDAqQwvtN60727.png"; name = "Fox 2000 Pictures"; "origin_country" = US; }, { id = 20555; "logo_path" = "/hD8yEGUBlHOcfHYbujp71vD8gZp.png"; name = "Taurus Film"; "origin_country" = DE; }, { id = 54051; "logo_path" = "<null>"; name = "Atman Entertainment"; "origin_country" = ""; }, { id = 54052; "logo_path" = "<null>"; name = "Knickerbocker Films"; "origin_country" = US; }, { id = 25; "logo_path" = "/qZCc1lty5FzX30aOCVRBLzaVmcp.png"; name = "20th Century Fox"; "origin_country" = US; }, { id = 4700; "logo_path" = "/A32wmjrs9Psf4zw0uaixF0GXfxq.png"; name = "The Linson Company"; "origin_country" = ""; } ); "production_countries" = ( { "iso_3166_1" = DE; name = Germany; }, { "iso_3166_1" = US; name = "United States of America"; } ); "release_date" = "1999-10-15"; revenue = 100853753; runtime = 139; "spoken_languages" = ( { "iso_639_1" = en; name = English; } ); status = Released; tagline = "Mischief. Mayhem. Soap."; title = "Fight Club"; video = 0; "vote_average" = "8.4"; "vote_count" = 19688; }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

coco_bauer

2020/07/23 15:48

Response から、どのような表を作ろうとしているのですか? Jsonデータ(Response)は、会社の表と、国の表、言語の表、の3つを含む構造になっていて、単純な表(TableView)では表しきれないのではないでしょうか? まずは、質問者がTableViewで表示した理想の形を質問に追加していただけませんか?
Ytan

2020/07/23 17:22

Qiitaの記事をTableviewに表示するようなのと同じようにこちらのAPI(映画情報関連)のタイトルを表示したいのですが、不可能ですかね? まだセルがタップされた時の事などは考えておりません。 またimageも取り出したいと思っているのでカスタムセルをxibファイルで制作すると思います。
guest

回答1

0

ベストアンサー

JSONのデコードでエラーが起きている理由は、期待しているJSONの構造と、実際にデコードしようとしている構造が異なるためです。

デコードは

Swift

1if let movies = try? decoder.decode([MovieStruct].self, from: data){

と配列としてデコードしようとしていますが、

レスポンスは

JSON

1{ 2 adult = 0; 3 "backdrop_path" = "/8iVyhmjzUbvAGppkdCZPiyEHSoF.jpg";

のように、配列になっていませんでした。

リクエスト先のAPIの仕様がわかりませんが、もし配列として取得できるのであれば配列として取得、できないのであればそれに合うように構造を見直すことになるかと思います。

ちなみに、

Swift

1 func fechData(){ 2 3 let url = URL(string: "https://api.themoviedb.org/3/movie/550?api_key=b562d3142fef5c7d35279900383f0850")! 4 URLSession.shared.dataTask(with: url) { (data, response, error) in 5 guard let data = data else { 6 print(error?.localizedDescription ?? "Unknown error") 7 return 8 } 9 10 let decoder = JSONDecoder() 11 // MovieStruct として取得する 12 if let movies = try? decoder.decode(MovieStruct.self, from: data){ 13 DispatchQueue.main.async { 14            // 一件のデータを配列に追加する 15 self.movies.append(movies) 16 self.movieTableView.reloadData() 17 } 18 }else{ 19 print("Unable parse JSON response") 20 } 21 }.resume() 22 }

とすればあまり大幅な変更をしなくても表示できます(もちろん、この先色々変更は必要になるとおもいますが)。

また、先々はカスタムセルにするのだとおもいますが、

Swift

1 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 2 let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 3 let movie = movies[indexPath.row] 4 5 cell.textLabel?.text = movie.title 6 // リリース日はとりあえず表示しない 7 //cell.textLabel?.text = movie.release_date 8 9 return cell 10 } 11}

提示されたコードだと映画名もリリース日も同じラベルに表示しているようです。

投稿2020/07/23 22:25

TsukubaDepot

総合スコア5086

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Ytan

2020/07/24 01:51

回答ありがとうございます。 この場合配列に入れている var movies = [MovieStruct]() この部分も変更しなければならないですか? 同じとこに表示してますね。 もう1つはdetailをtext表示するつもりでした。すみません。
TsukubaDepot

2020/07/24 02:24

まずはやってみてはいかがでしょうか。 やってみれば、結果は明確ですし、それでわからなければまたご質問されるのがいいかと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問