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

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

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

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

Q&A

1回答

633閲覧

Decodableを利用したJSONデータのパースに関して

takataka1

総合スコア9

Swift

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

0グッド

0クリップ

投稿2018/07/20 16:52

JSONレスポンスは下になります。

JSON

1{ 2 "info": { 3 "photo_num": ###, 4 "photo": [ 5 { 6 "photo_id": ###, 7 "user_id": ###, 8 "album_id": ###, 9 "photo_title": "タイトル", 10 "favorite_num": ###, 11 "comment_num": ###, 12 "view_num": ###, 13 "copyright": "normal/creativecommons", 14 "copyright_commercial": "yes/no" 15 "copyright_modifications": "yes/no/share" 16 "original_height": ##, 17 "original_width": ###, 18 "geo": { 19 "latitude": ###, 20 "longitude": ### 21 }, 22 "date": "YYYY-MM-DD", 23 "regist_time": "YYYY-MM-DDThh:mm:ss+09:00", 24 "url": "URL", 25 "image_url": "URL", 26 "original_image_url": "URL", 27 "thumbnail_image_url": "URL", 28 "large_tag": "<a href=\"...\">...</a>", 29 "medium_tag": "<a href=\"...\">...</a>" 30 }, 31 ... 32 ] 33 } 34}

上の中にある"image_url"を取り出したく下のようにコードを記載しました

Swift

1 Alamofire.request(url, method: .get, parameters: params, encoding: URLEncoding.default, headers: nil).responseData { (dataResponse) in 2 3 if let err = dataResponse.error{ 4 print("failed to contact photos", err) 5 return 6 } 7 8 guard let data = dataResponse.data else {return} 9 10 do{ 11 let searchResult = try JSONDecoder().decode(SearchResults.self, from: data) 12 self.photos = searchResult.info.photo! 13 self.collectionView.reloadData() 14 15 }catch let decodeErr{ 16 print("failed to decode:", decodeErr) 17 } 18 } 19 20 struct SearchResults: Decodable { 21 22 struct Photo: Decodable{ 23 let photo_num: Int? 24 let photo: [Photos]? 25 } 26 let info: Photo 27 } 28 29class Photos: Decodable{ 30 var image_url: String? 31 var original_image_url: String? 32} 33

しかし以下のようなエラーメッセージが出ます。

failed to decode: keyNotFound(CodingKeys(stringValue: "info", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: "info", intValue: nil) ("info").", underlyingError: nil))

failed to decode: keyNotFound(CodingKeys(stringValue: "info", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: "info", intValue: nil) ("info").", underlyingError: nil))
failed to decode: keyNotFound(CodingKeys(stringValue: "info", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: "info", intValue: nil) ("info").", underlyingError: nil))

どなたか対処法をご教示いただけないでしょうか。

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

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

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

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

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

fuzzball

2018/07/23 04:56

Decodableを使わないとダメなんでしょうか?
guest

回答1

0

とりあえずPlaygroundで動く状態に書いてみました、試してみてください。

swift

1import Foundation 2 3extension KeyedDecodingContainer { 4 func decode<ResultType: Decodable>(forKey key: Key, defaultValue: ResultType) -> ResultType { 5 return (try? decode(ResultType.self, forKey: key)) ?? defaultValue 6 } 7} 8 9var data = """ 10{ 11 "info": { 12 "photo_num": "abc", 13 "photo": [ 14 { 15 "photo_id": "", 16 "user_id": "", 17 "album_id": "", 18 "photo_title": "タイトル", 19 "favorite_num": "", 20 "comment_num": "", 21 "view_num": "", 22 "copyright": "normal/creativecommons", 23 "copyright_commercial": "yes/no", 24 "copyright_modifications": "yes/no/share", 25 "original_height": "", 26 "original_width": "", 27 "geo": { 28 "latitude": "", 29 "longitude": "" 30 }, 31 "date": "YYYY-MM-DD", 32 "regist_time": "YYYY-MM-DDThh:mm:ss+09:00", 33 "url": "URL", 34 "image_url": "URL - image_url", 35 "original_image_url": "URL - original_image_url", 36 "thumbnail_image_url": "URL", 37 "large_tag": "<a href=\\"...\\">...</a>", 38 "medium_tag": "<a href=\\"...\\">...</a>" 39 } 40 ] 41 } 42} 43""".data(using: .utf8) 44 45// \u{22} 46 47struct SearchResults: Codable { 48 let info: Photos 49} 50 51struct Photos: Codable { 52 let photo_num: String 53 let photo: [Photo] 54} 55 56struct Photo: Codable { 57 58 let photoId: String 59 let userId: String 60 let albumId: String 61 let photoTitle: String 62 let favoriteNum: String 63 let commentNum: String 64 let viewNum: String 65 let copyright: String 66 let copyrightCommercial: String 67 let copyrightModifications: String 68 let originalHeight: String 69 let originalWidth: String 70 let geo: Geo 71 let date: String 72 let registTime: String 73 let url: String 74 let imageUrl: String 75 let originalImageUrl: String 76 let thumbnailImageUrl: String 77 let largeTag: String 78 let mediumTag: String 79 80 enum CodingKeys: String, CodingKey { 81 82 case photoId = "photo_id" 83 case userId = "user_id" 84 case albumId = "album_id" 85 case photoTitle = "photo_title" 86 case favoriteNum = "favorite_num" 87 case commentNum = "comment_num" 88 case viewNum = "view_num" 89 case copyright 90 case copyrightCommercial = "copyright_commercial" 91 case copyrightModifications = "copyright_modifications" 92 case originalHeight = "original_height" 93 case originalWidth = "original_width" 94 case geo 95 case date 96 case registTime = "regist_time" 97 case url 98 case imageUrl = "image_url" 99 case originalImageUrl = "original_image_url" 100 case thumbnailImageUrl = "thumbnail_image_url" 101 case largeTag = "large_tag" 102 case mediumTag = "medium_tag" 103 } 104 105 init(from decoder: Decoder) throws { 106 let container = try decoder.container(keyedBy: CodingKeys.self) 107 photoId = container.decode(forKey: .photoId, defaultValue: "") 108 userId = container.decode(forKey: .userId, defaultValue: "") 109 albumId = container.decode(forKey: .albumId, defaultValue: "") 110 photoTitle = container.decode(forKey: .photoTitle, defaultValue: "") 111 favoriteNum = container.decode(forKey: .favoriteNum, defaultValue: "") 112 commentNum = container.decode(forKey: .commentNum, defaultValue: "") 113 viewNum = container.decode(forKey: .viewNum, defaultValue: "") 114 copyright = container.decode(forKey: .copyright, defaultValue: "") 115 copyrightCommercial = container.decode(forKey: .copyrightCommercial, defaultValue: "") 116 copyrightModifications = container.decode(forKey: .copyrightModifications, defaultValue: "") 117 originalHeight = container.decode(forKey: .originalHeight, defaultValue: "") 118 originalWidth = container.decode(forKey: .originalWidth, defaultValue: "") 119 geo = try container.decode(Geo.self, forKey: .geo) 120 date = container.decode(forKey: .date, defaultValue: "") 121 registTime = container.decode(forKey: .registTime, defaultValue: "") 122 url = container.decode(forKey: .url, defaultValue: "") 123 imageUrl = container.decode(forKey: .imageUrl, defaultValue: "") 124 originalImageUrl = container.decode(forKey: .originalImageUrl, defaultValue: "") 125 thumbnailImageUrl = container.decode(forKey: .thumbnailImageUrl, defaultValue: "") 126 largeTag = container.decode(forKey: .largeTag, defaultValue: "") 127 mediumTag = container.decode(forKey: .mediumTag, defaultValue: "") 128 } 129} 130 131struct Geo: Codable { 132 let latitude: String 133 let longitude: String 134} 135 136 137 138// Decode 139let searchResult = try? JSONDecoder().decode(SearchResults.self, from: data!) 140if let searchResult = searchResult { 141 142 print(searchResult.info.photo.first?.imageUrl) 143 //=> Optional("URL - image_url") 144 print(searchResult.info.photo.first?.originalImageUrl) 145 //=> Optional("URL - original_image_url") 146} 147

投稿2018/07/23 04:32

_Kentarou

総合スコア8490

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問