前提・実現したいこと
http://127.0.0.1:3000のAPIから返ってきたネストしたJSONから値を取得して表示したい。
Swift初学者でして、ネストしたJSONを構造体に変換する部分や値の取得などがうまくいきません。
解決方法をお教えいただけますと幸いです。
http://127.0.0.1:3000/api/posts.jsonで以下のようなJSONがある場合、Swift側ではどのように構造体や変数を定義すれば良いでしょうか??
(APIの部分はRuby on Railsで実装しております。)
{ "posts": [ { "id": 1, "user_id": 1, "content": "テスト", "status": "public", "created_at": "2021-03-04T06:44:55.317+09:00", "updated_at": "2021-03-07T20:43:28.347+09:00", "photos": [ { "image": { "url": "/uploads/post_photo/image/1/2018-06-29_12.13.21.jpg", "thumb": { "url": "/uploads/post_photo/image/1/thumb_2018-06-29_12.13.21.jpg" } } } ] } ] }
現状は、以下のようにしております。
struct PostModel: Decodable { var posts: [Post] } struct Post: Decodable, Identifiable, Encodable { var photo: [Photo] var id: Int? var user_id: Int? var content: String var status: String var created_at: String var updated_at: String struct Photo: Decodable, Encodable { var image: [Image] struct Image: Decodable, Encodable { var url: String var thumb: [Thumb] struct Thumb: Decodable, Encodable { var url: String } } } }
APIの通信部分はAlamofireで実装しております。
class PostModelFetcher: ObservableObject { @Published var postData: [Post] = [] init() { fetchPostData() } func fetchPostData() { AF.request("http://127.0.0.1:3000/api/posts.json", method: .get, encoding: URLEncoding.default).response { response in guard let json = response.data else { return } let decoder: JSONDecoder = JSONDecoder() do { let searchedResultData = try decoder.decode(PostModel.self, from: json) DispatchQueue.main.async { self.postData = searchedResultData.posts.reversed() } } catch { print("json convert failed in JSONDecoder. " + error.localizedDescription) } debugPrint(response) } } }
リストのセルのViewは以下のように実装しております。(このViewに上記JSONのposts.photos.image.urlなどネストしたデータを表示したいです。)
struct PostRowView: View { var postData: Post var body: some View { VStack(alignment: .leading) { Text(postData.content) .bold() .font(.headline) .lineLimit(2) .padding(Edge.Set.top, 8.0) .padding(Edge.Set.bottom, 12.0) } } } struct PostDetailView: View { var postData: Post var body: some View { Text("Hello, World!") } }
トップページのViewは以下のように実装しております。
struct ContentView: View { @ObservedObject var fetcher = PostModelFetcher() var body: some View { NavigationView { List(fetcher.postData) { post in NavigationLink(destination: PostDetailView(postData: post)) { PostRowView(postData: post) } } .navigationBarTitle(Text("投稿一覧")) } } }
API通信は以下のように出来ているのですが、json convert failed in JSONDecoder. The data couldn’t be read because it is missing.のエラーが発生しているため構造体の定義の方法などが間違っていると思い質問いたしました。
2021-08-28 18:12:55.048637+0900 RelatedModelApi[1356:1479807] [] nw_protocol_get_quic_image_block_invoke dlopen libquic failed json convert failed in JSONDecoder. The data couldn’t be read because it is missing. [Request]: GET http://127.0.0.1:3000/api/posts.json [Headers]: None [Body]: None [Response]: [Status Code]: 200 [Headers]: Cache-Control: max-age=0, private, must-revalidate Content-Type: application/json; charset=utf-8 Etag: W/"4cef57ad653583235e93452a6f553c45" Referrer-Policy: strict-origin-when-cross-origin Transfer-Encoding: Identity X-Content-Type-Options: nosniff X-Download-Options: noopen X-Frame-Options: SAMEORIGIN X-Permitted-Cross-Domain-Policies: none X-Rack-Dev-Mark-Env: development X-Request-Id: 34f6c77f-2925-42bc-bbfd-adbc11b66e35 X-Runtime: 0.104696 X-XSS-Protection: 1; mode=block [Body]: {"posts":[{"id":1,"user_id":1,"content":"テスト","status":"public","created_at":"2021-03-04T06:44:55.317+09:00","updated_at":"2021-03-07T20:43:28.347+09:00","photos":[{"image":{"url":"/uploads/post_photo/image/1/2018-06-29_12.13.21.jpg","thumb":{"url":"/uploads/post_photo/image/1/thumb_2018-06-29_12.13.21.jpg"}}}]}]} [Network Duration]: 0.955036997795105s [Serialization Duration]: 0.0s [Result]: success(Optional(495 bytes))
現状は、構造体の以下の部分を削除すればPost単体のデータは取得してセルに表示出来るという所までは分かっております。
var photo: [Photo] ... struct Photo: Decodable, Encodable { var image: [Image] struct Image: Decodable, Encodable { var url: String var thumb: [Thumb] struct Thumb: Decodable, Encodable { var url: String } } }
しかし、上記のPhotoとImageなども一緒にセルに表示したいです!!!
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/08/28 12:19
2021/08/28 12:33
2021/08/28 13:15
2021/08/28 13:30
2021/08/29 01:54
2021/08/29 03:31 編集
2021/08/29 03:36
2021/08/29 03:41