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

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

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

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

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

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

1回答

1092閲覧

ネストされたJSONデータをAlamofireで取得する方法

duck015

総合スコア29

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

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

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

0クリップ

投稿2020/01/22 09:05

編集2020/01/23 02:27

前提・実現したいこと

AlamofireSwiftyJSONを使い、下記JSONデータの"title"を取得したいです。
ネストされており、参考記事とデータ構造が異なるため、取得方法が分からないでいます。
どなたかご教示いただけませんでしょうか?

JSONデータ

{ "result": true, "data": [ { "type": "タイプ1", "article": { "id": "123", "title": "タイトル1" } }, { "article": { "id": "456", "title": "タイトル2" }, "type": "タイプ2" }  ] }

試したこと

下記の通りコードを書きましたが、nilとなってしましいます。

Swift

1func getArticles() { 2 Alamofire.request("url").validate().responseJSON { response in 3// print(response.result.value) 4 5 guard let object = response.result.value else { 6 return 7 } 8 let json = JSON(object) 9 json["data"].forEach { (_, json) in 10 let type = json["title"].string! //Unexpectedly found nil while unwrapping an Optional value 11 print(type) 12 } 13 } 14 }

参考記事

Swift3 + Alamofire4 + SwiftyJSONでJSONレスポンスをパースするサンプル
AlamofireとSwiftyJSONでAPIを叩くチュートリアル

追記

ブレイクポイント

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

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

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

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

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

MasatoUchida

2020/01/22 09:57

forEach内のjsonはtypeかarticleしかないように見えます。
duck015

2020/01/22 14:12

コメントありがとうございます。 typeかarticleしかないとはどういうことでしょうか? 理解不足で申し訳ございませんが、ご教示いただけると幸いです。
MasatoUchida

2020/01/23 02:09

試しにarticleを出力し、ブレークポイントを置いて中身を確認してみてください。
duck015

2020/01/23 02:29

下記で試してみたところ、おっしゃる通り、type,articleのみでした(画像追加しました)。 ただ、Unexpectedly found nil...〜 となりエラーになってしまいます。 json["data"].forEach { (_, json) in let type = json["article"].string! print(type) }
guest

回答1

0

ベストアンサー

中々たどり着かないようなので回答します。
duck015さんの現状コードだと、下記のような認識になります。

Json

1// Responseクラス 2{ 3 "result": true, 4 // Dataクラス 5 "data": [ 6 { 7 "type": "タイプ1", 8 // Articleクラス 9 "article": { 10 "id": "123", 11 "title": "タイトル1" 12 } 13 }, 14 { 15 "article": { 16 "id": "456", 17 "title": "タイトル2" 18 }, 19 "type": "タイプ2" 20 } 21 ] 22}

Swift

1struct Response { 2 let result : bool 3 let data: Data 4} 5 6struct Data { 7 let type : String 8 let article : Article 9} 10 11struct Article { 12 let id : Int 13 let title : String 14} 15 16// メソッド名省略 17{ 18 Alamofire.request("url").validate().responseJSON { response in 19 guard let object = response.result.value else { 20 return 21 } 22 let json = JSON(object) // jsonはResponseクラス 23 // わかりやすくするため変数名を変えてます 24 // resultはbool値 25 // dataはDataクラス 26 json["data"].forEach { (result, data) in 27 // Dataクラスにはtitleはない!!! 28 let type = json["title"].string! //Unexpectedly found nil while unwrapping an Optional value 29 print(type) 30 } 31 } 32}

実際には構造体ではなくDictionaryですが、イメージとしては上記のような感じです。
つまりtitleを参照したいならArticle構造体を参照しなければならないという事です。
Dictonaryのアクセスの仕方はjson["data"]でご存知のようなので割愛します。
もしこれでも分からない場合は、ここは勉強した上で質問する場所ですので、一度jsonに関する知識を勉強なさった方がいいかと思います。

投稿2020/01/23 02:46

MasatoUchida

総合スコア134

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

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

duck015

2020/01/23 03:05

MasatoUchida様 ご回答いただきありがとうございます。 jsonの構造をうまく把握できていませんでした。 頭を整理することができ、下記コードにより取得することができました。 ありがとうございました! json["data"].forEach { (_, json) in let type = json["article"]["title"].string! print(type) }
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問