NEW: Start my new Ultimate Portfolio App course with a free Hacking with Swift+ trial! >>

SOLVED: Building the structs for API

Forums > SwiftUI

Hello, how to build a structs to read this structuer of API I did this

struct Post: Codable, Identifiable{
    var id : String
    var caption: String
    var date : String
    var imageDownloadURL : String

}

API structure

  {
  "posts": {
      "-MTal_snEEAdx7wTcqpL": {
      "NumberOfLikes": 3,
      "caption": "Yellow 🌙🌙🌙🌙🌙 moon",
      "date": "23 Feb 2021 at 5:56:1 AM",
      "edited": true,
      "id": "2khpsHcxPZdRApZ2eIXbuOrBajA3",
      "imageDownloadURL": "https://-------",
      "postID": "-MTal_snEEAdx7wTcqpL"
    },
    "-MTawPLC_lz-0p18x0CZ": {
      "NumberOfLikes": 4,
      "caption": "Sunset 😍😍😍😍",
      "date": "23 Feb 2021 at 5:57:55 AM",
      "edited": true,
      "id": "2khpsHcxPZdRApZ2eIXbuOrBajA3",
      "imageDownloadURL": "https://-------------",
      "postID": "-MTawPLC_lz-0p18x0CZ"
      }
    }
    }

   

There is an easy way to do this and a hard way.

The easy way is to just decode the JSON to a dictionary:

import Foundation

struct Response: Codable {
    var posts: [String: Post]
}

struct Post: Codable, Identifiable {
    var postID : String
    var caption: String
    var date : String
    var imageDownloadURL : String
    var id: String { postID }
}

let jsonData = """
{
  "posts": {
      "-MTal_snEEAdx7wTcqpL": {
      "NumberOfLikes": 3,
      "caption": "Yellow 🌙🌙🌙🌙🌙 moon",
      "date": "23 Feb 2021 at 5:56:1 AM",
      "edited": true,
      "id": "2khpsHcxPZdRApZ2eIXbuOrBajA3",
      "imageDownloadURL": "https://-------",
      "postID": "-MTal_snEEAdx7wTcqpL"
    },
    "-MTawPLC_lz-0p18x0CZ": {
      "NumberOfLikes": 4,
      "caption": "Sunset 😍😍😍😍",
      "date": "23 Feb 2021 at 5:57:55 AM",
      "edited": true,
      "id": "2khpsHcxPZdRApZ2eIXbuOrBajA3",
      "imageDownloadURL": "https://-------------",
      "postID": "-MTawPLC_lz-0p18x0CZ"
      }
    }
}
""".data(using: .utf8)!

let decoder = JSONDecoder()
var response: Response? = nil
do {
    response = try decoder.decode(Response.self, from: jsonData)
}
catch {
    print(error)
}

print(response)

The hard way involves treating the posts object of the JSON response as having dynamic keys and then doing something like this article discusses: Decode and Flatten JSON with Dynamic Keys Using Decodable

1      

Thank you, I used your srtucts to fetch data from API, and it worked. but I want to assign response to an array of posts so I can use it inside ForEach just like:

 @Published var posts = [Post]()
let request = URLRequest(url: url)

        URLSession.shared.dataTask(with: request) {data, response, error in
            if let data = data {

                let decoder = JSONDecoder()

                do {
                    request = try decoder.decode([Post].self, from: data)
                    self.posts.append(request)
                    print(request)
                }
                catch {
                    print(error)
                }

            }
            print("error")

        }.resume()

   

Easy peasy. You can do something like this:

do {
    let response = try decoder.decode(Response.self, from: data)
    self.posts = response.posts.values.compactMap { $0 }
}
catch {
    print(error)
}

But you might need to wrap the line where you set self.posts in a DispatchQueue since it's updating an @Published property which in turn can affect the UI. I'm not certain of that, so make sure you test it.

1      

Thank you, It workes like I want it to work, yes I wraped it iside DispatchQueue.

 DispatchQueue.main.async {
                        self.posts = response.posts.values.compactMap { $0 }
                    }

   

Hacking with Swift is sponsored by Instabug

SPONSORED Catch bugs as soon as they happen and know exactly why a crash occurred. Instabug's SDK grabs all the logs they need to fix bugs, crashes and performance issues in minutes instead of days. Get screenshots, device details, network logs, repro steps, and tons of other critical insights needed to resolve issues and prioritize product backlogs straight from your dashboard. It only takes a minute to integrate!

Get started now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.