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

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

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

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Swift

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

Q&A

解決済

1回答

565閲覧

json形式への変化処理 swift

aa23021

総合スコア3

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Swift

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

0グッド

0クリップ

投稿2020/06/11 14:29

編集2020/06/12 09:39

##API

{ result: [ { foodImageUrl: "https://image.space.rakuten.co.jp/d/strg/ctrl/3/fbd7dd260d736654532e6c0b1ec185a0cede8675.49.2.3.2.jpg", recipeDescription: "そのままでも、ご飯にのせて丼にしても♪", recipePublishday: "2017/10/10 22:37:34", shop: 0, pickup: 0, recipeId: 1760028309, nickname: "はぁぽじ", smallImageUrl: "https://image.space.rakuten.co.jp/d/strg/ctrl/3/fbd7dd260d736654532e6c0b1ec185a0cede8675.49.2.3.2.jpg?thum=55", recipeMaterial: [ "鶏むね肉", "塩", "酒", "片栗粉", "○水", "○塩", "○鶏がらスープの素", "○黒胡椒", "長ネギ", "いりごま", "ごま油" ], recipeIndication: "約10分", recipeCost: "300円前後", rank: "1", recipeUrl: "https://recipe.rakuten.co.jp/recipe/1760028309/", mediumImageUrl: "https://image.space.rakuten.co.jp/d/strg/ctrl/3/fbd7dd260d736654532e6c0b1ec185a0cede8675.49.2.3.2.jpg?thum=54", recipeTitle: "ご飯がすすむ!鶏むね肉のねぎ塩焼き" },

##やりたいこと

foodImageUrlをとってtableviewに表示させたい。

##試したコード

import UIKit struct ResultUserList: Codable { var result: User struct User: Codable{ var foodImageUrl: String } } class ResultViewModel { static func fetchArticle(completion: @escaping ([ResultUserList]) -> Swift.Void) { let url = "https://app.rakuten.co.jp/services/api/Recipe/CategoryRanking/20170426?format=json&applicationId=1095609837981916624" guard var urlComponents = URLComponents(string: url) else { return } //URLQueryItemを使うことでURLのクエリストリングを追加して、ページの要素数を50までと指定 urlComponents.queryItems = [ URLQueryItem(name: "per_page", value: "50"), ] let task = URLSession.shared.dataTask(with: urlComponents.url!) { data, response, error in guard let jsonData = data else { return } do{ let articles = try JSONDecoder().decode([ResultUserList].self, from: jsonData) completion(articles) } catch { print(error.localizedDescription) } } task.resume() } } class ViewController: UIViewController { private var tableView = UITableView() fileprivate var articles: [ResultUserList] = [] override func viewDidLoad() { super.viewDidLoad() self.title = "レシピ" tableView.dataSource = self tableView.frame = view.frame view.addSubview(tableView) ResultViewModel.fetchArticle(completion: { (articles) in self.articles = articles DispatchQueue.main.async { self.tableView.reloadData() } }) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } } extension ViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cell") let article = articles[indexPath.row] cell.textLabel?.text = article.result.foodImageUrl return cell } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return articles.count } }

よろしくお願いします。

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

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

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

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

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

kei344

2020/06/11 14:34

使用している言語のタグをつけましょう。
aa23021

2020/06/11 14:41

ご指摘ありがとうございます。 編集いたしました。
hayabusabusash

2020/06/12 06:50

どんなデータを json の形式に変換しようとしているのか知りたいので、 引数に指定している data はどんなデータなのかを追記していただけないでしょうか?
aa23021

2020/06/12 09:42 編集

すみません。昨日から色々試しすぎて、上記のエラーがどれで出たのが忘れてしまいました。汗 昨日から困っている詳細を編集いたしましたので、教えていただけると嬉しいです。 宜しくお願いします。
guest

回答1

0

ベストアンサー

追記ありがとうございます????‍♂️

貼っていただいたモデルオブジェクトを確認したところ
一部問題があったので修正してみました。

Swift

1struct ResultUserList: Codable { 2 // result の中は配列になっているので、`User` の配列に変更 3 let result: [User] 4} 5 6struct User: Codable { 7 let foodImageUrl: String 8}

貼っていただいた Json の中の result の中は配列として返ってきているので、
モデルオブジェクトの方も配列にしてみました。これで問題なくデコードができると思います。

一応以下のコードを Playground で実行してエラーが出ないことは確認しました。

Swift

1import Foundation 2 3let json = """ 4{ 5 "result": [ 6 { 7 "foodImageUrl": "https://image.space.rakuten.co.jp/d/strg/ctrl/3/fbd7dd260d736654532e6c0b1ec185a0cede8675.49.2.3.2.jpg", 8 "recipeDescription": "そのままでも、ご飯にのせて丼にしても♪", 9 "recipePublishday": "2017/10/10 22:37:34", 10 "shop": 0, 11 "pickup": 0, 12 "recipeId": 1760028309, 13 "nickname": "はぁぽじ", 14 "smallImageUrl": "https://image.space.rakuten.co.jp/d/strg/ctrl/3/fbd7dd260d736654532e6c0b1ec185a0cede8675.49.2.3.2.jpg?thum=55", 15 "recipeMaterial": [ 16 "鶏むね肉", 17 "塩", 18 "酒", 19 "片栗粉", 20 "○水", 21 "○塩", 22 "○鶏がらスープの素", 23 "○黒胡椒", 24 "長ネギ", 25 "いりごま", 26 "ごま油" 27 ], 28 "recipeIndication": "約10分", 29 "recipeCost": "300円前後", 30 "rank": "1", 31 "recipeUrl": "https://recipe.rakuten.co.jp/recipe/1760028309/", 32 "mediumImageUrl": "https://image.space.rakuten.co.jp/d/strg/ctrl/3/fbd7dd260d736654532e6c0b1ec185a0cede8675.49.2.3.2.jpg?thum=54", 33 "recipeTitle": "ご飯がすすむ!鶏むね肉のねぎ塩焼き" 34 } 35 ] 36} 37""".data(using: .utf8)! 38 39struct ResultUserList: Codable { 40 let result: [User] 41} 42 43struct User: Codable { 44 let foodImageUrl: String 45} 46 47do { 48 let resultUserList = try JSONDecoder().decode(ResultUserList.self, from: json) 49 print(resultUserList.result) 50} catch { 51 print(error) 52} 53

あと貼っていただいたコードでは [ResultUserList] としてデコードしようとしていますが、
ResultUserLiset に修正したほうがいいと思います。
foodImageUrl とその他諸々を一覧として出したいなら、[User] を結果として完了ハンドラに返してあげればいいはずです。

Swift

1 let task = URLSession.shared.dataTask(with: urlComponents.url!) { data, response, error in 2 3 guard let jsonData = data else { 4 return 5 } 6 do{ 7 // デコード先を `ResultUserList` に変更. 8 let resultUserList = try JSONDecoder().decode(ResultUserList.self, from: jsonData) 9 // `ResultUserList` の `result` プロパティから `[User]` を取り出して結果として返す. 10 completion(resultUserList.result) 11 } catch { 12 print(error.localizedDescription) 13 } 14 } 15 task.resume()

コメントいただいた件を追記(2020/06/12)

上記のコードをそのまま部分的に変えても動かないので、
static メソッドの完了ハンドラの型、TableView の dataSource として使っている変数の型も変える必要があると思います。
この辺りは自分が書いたコードではなく全体を把握できているわけではないので、エラーを頼りに適宜修正してもらえると嬉しいです????‍♂️

Swift

1// ViewModel の static メソッド 2// 完了ハンドラに返す型を `[User]` に変更します. 3static func fetchArticle(completion: @escaping ([User]) -> Swift.Void) { 4 // 省略します 5} 6 7// ViewController 内の TableView の dataSource として使っている変数 8// [User] に変更します. 9fileprivate var articles: [User] = []

投稿2020/06/12 10:54

編集2020/06/12 13:38
hayabusabusash

総合スコア767

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

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

aa23021

2020/06/12 11:27

ご丁寧に本当に有り難うございます。 上記のように変えた場合、 ``` do{ // デコード先を `ResultUserList` に変更. let resultUserList = try JSONDecoder().decode(ResultUserList.self, from: jsonData) // `ResultUserList` の `result` プロパティから `[User]` を取り出して結果として返す. completion(resultUserList.result) ←エラーCannot convert value of type '[User]' to expected argument type '[ResultUserList]' ``` が出てしまうのと、 下の ``` extension ViewController: UITableViewDataSource { func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = UITableViewCell(style: .subtitle, reuseIdentifier: "cell") let article = resultUserList[indexPath.row] cell.textLabel?.text = article.result ← エラー:Cannot assign value of type '[User]' to type 'String' ``` と出てしまうのですが。 一応、二番目のエラーは、 .foodImageUrl つけてみたり .User つけてもどれもエラーが出てしまいました。 長々とすみませんが、よろしくお願いします。
hayabusabusash

2020/06/12 13:39

コメントいただいた件について少し追記しました????‍♂️
aa23021

2020/06/24 13:15

大変遅くなりました。ベストアンサーで選んだつもりが反映されてなかったです。汗 貴重な時間くださいありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問