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

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

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

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

Swift

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

Q&A

解決済

1回答

776閲覧

JSONのデータを取得したい

aoringo

総合スコア23

Xcode

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

Swift

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

0グッド

0クリップ

投稿2022/05/04 05:32

編集2022/05/04 07:59

概要

リクエストURLからwebAPIを用いて、JSONデータを取得したいのですが、うまく取得できずnilが帰ってきます。
エラーなども特になく、URLも間違っていなさそうなのですが、どこが間違っているのかわからず、、、

Fiddlerで調べたところ、リクエストURLがそもそも踏まれていない場合もあり(踏んではいるがデータが取得できてない場合もある)、解決方法がわかりません。
ご教授よろしくお願い致します。

(開発に期限があり迫っているため、一刻も早く解決したくqiitaにも載せております。)

帰ってくるJSONデータ

ResultJson(item: nil)

コード

Swift

1import UIKit 2 3class ResultViewController: UIViewController { 4 5 var r_lat = 0.0 //緯度 6 var r_lon = 0.0 //経度 7 var r_rad = 0 //半径 8 9 override func viewDidLoad() { 10 super.viewDidLoad() 11 12 r_lat = UserDefaults.standard.double(forKey: "lat") //UserDefaultsの緯度を代入 13 print("緯度:\(r_lat)") 14 r_lon = UserDefaults.standard.double(forKey: "lon") //UserDefaultsの経度を代入 15 print("経度:\(r_lon)") 16 r_rad = UserDefaults.standard.integer(forKey: "rad") //UserDefaultsの半径を代入 17 print("半径:\(r_rad)") 18 19 search(lat: r_lat, lon: r_lon, rad: r_rad) 20 21 } 22 23 //JSONのitem内のデータ構造 24 struct ItemJson: Codable { 25 26 let name: String? //店舗の名称 27 let mobile_access: String? //交通アクセス 28 let logo_image: String? //ロゴ画像 29 } 30 31 //JSONのデータ構造 32 struct ResultJson: Codable { 33 34 let item:[ItemJson]? //複数要素 35 } 36 37 //searchメソッド 38 func search(lat: Double, lon: Double, rad: Int) { 39 //リクエストURLの組み立て 40 guard let req_url = URL(string: "http://webservice.recruit.co.jp/hotpepper/gourmet/v1/?key=[APIキー(コードでは入れています)]&lat=\(lat)&lng=\(lon)&range=\(rad)&order=4&format=json") else { 41 return 42 } 43 print(req_url) 44 45 let req = URLRequest(url: req_url) //リクエストに必要な情報を生成 46 let session = URLSession(configuration: .default, delegate: nil, delegateQueue: OperationQueue.main) //データ転送を管理するためのセッションを生成 47 //print("session:\(session)") 48 let task = session.dataTask(with: req, completionHandler: { 49 (data , response , error) in 50 session.finishTasksAndInvalidate() //セッションを終了 51 //do try catchエラーハンドリング 52 do { 53 let decoder = JSONDecoder() //JSONDecoderのインスタンスを取得 54 //print("decoder:\(decoder)") 55 let json = try decoder.decode(ResultJson.self, from: data!) //受け取ったJSONデータを解析して格納 56 print("json:\(json)") 57 } catch { 58 print("エラー") //エラー処理 59 } 60 }) 61 task.resume() //ダウンロード開始 62 63 } 64}

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2022/05/04 06:33

Fiddler などのキャプチャツールを使って要求・応答が期待通りになっているかは調べたのでしょうか?
aoringo

2022/05/04 06:36

Fiddlerというもの自体知りませんでした、、
aoringo

2022/05/04 07:54

了解いたしました。無知で、申し訳ございません。
hoshi-takanori

2022/05/04 22:08

let item:[ItemJson]? のところ、item じゃなくて shop なのでは…。 (というか、decode する前に返ってきた JSON をよく観察しましょう。)
guest

回答1

0

ベストアンサー

https://webservice.recruit.co.jp/doc/hotpepper/reference.html

APIリファレンスを参照しますと、レスポンスは次のようなものになると思います(必要そうな項目だけ抜粋して自分で作ってみました)。

json

1{ 2 "results": { 3 "api_version": 1.20, 4 "results_available": 2, 5 "results_returned": 2, 6 "results_start": 1, 7 "shop": [ 8 { 9 "id": "J999999999", 10 "name": "居酒屋 ホットペッパー", 11 "logo_image": "https://test.domain/logo.png", 12 "mobile_access": "銀座一丁目駅10番出口徒歩3分" 13 }, 14 { 15 "id": "J999999992", 16 "name": "居酒屋 ホットペッパー2", 17 "logo_image": "https://test.domain/logo2.png", 18 "mobile_access": "銀座一丁目駅10番出口徒歩3分2" 19 } 20 ] 21 } 22}

レスポンスに合わせてresultsやshopなどの構造体を作ると良いと思います。

swift

1//JSONのitem内のデータ構造 2struct ItemJson: Codable { 3 4 let name: String? //店舗の名称 5 let mobile_access: String? //交通アクセス 6 let logo_image: String? //ロゴ画像 7} 8 9// ***** Results追加 10struct Results: Codable { 11 let shop: [ItemJson]? 12} 13 14//JSONのデータ構造 15struct ResultJson: Codable { 16 // ***** resultsに変更 17 // let item:[ItemJson]? //複数要素 18 let results: Results? 19} 20 21//searchメソッド 22func search(lat: Double, lon: Double, rad: Int) { 23 //リクエストURLの組み立て 24 guard let req_url = URL(string: "http://webservice.recruit.co.jp/hotpepper/gourmet/v1/?key=[APIキー(コードでは入れています)]&lat=\(lat)&lng=\(lon)&range=\(rad)&order=4&format=json") else { 25 return 26 } 27 print(req_url) 28 29 let req = URLRequest(url: req_url) //リクエストに必要な情報を生成 30 let session = URLSession(configuration: .default, delegate: nil, delegateQueue: OperationQueue.main) //データ転送を管理するためのセッションを生成 31 //print("session:\(session)") 32 let task = session.dataTask(with: req, completionHandler: { 33 (data , response , error) in 34 session.finishTasksAndInvalidate() //セッションを終了 35 //do try catchエラーハンドリング 36 do { 37 let decoder = JSONDecoder() //JSONDecoderのインスタンスを取得 38 //print("decoder:\(decoder)") 39 let json = try decoder.decode(ResultJson.self, from: data!) //受け取ったJSONデータを解析して格納 40 print("json:\(json)") 41 } catch { 42 print("エラー") //エラー処理 43 } 44 }) 45 task.resume() //ダウンロード開始 46 47}

プロパティの名前を変えたいなどありましたら、次のリンク先にあるサンプルなどもダウンロードして動かしてみると良いかもしれません。
https://developer.apple.com/documentation/foundation/archives_and_serialization/using_json_with_custom_types

投稿2022/05/04 08:14

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

aoringo

2022/05/04 08:22

解決致しました!ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問