Home > front end >  SwiftUI List and URLSession JSONDecode
SwiftUI List and URLSession JSONDecode

Time:11-26

hi everyone I'm newbie in Swift I ask for help why the data is not displayed in List? Please help me a fix it. I make a Model Data, and take a data from URl and parse it

My model:

struct ResponseData:  Codable{
    var userId: String
    var id: String
    var title: String
    var body: String
}

My code in Content view:

import SwiftUI

struct ContentView: View {
    @State var responseData = [ResponseData]()
    
    var body: some View {
        List(responseData, id: \.id ) { item in
            Text("\(item.body)")
        }
        .task {
            await loadData()
        }
    }

    func loadData () async {
        
        let urlString = "https://jsonplaceholder.typicode.com/posts"
        guard let url = URL(string: urlString) else { return }
        
        URLSession.shared.dataTask(with: url) { (data, response, error) in
            guard let data = data else {return}
            guard error == nil else {return}
            do {
                let postData = try JSONDecoder().decode(ResponseData.self, from: data)
            } catch let error {
                print(error)
            }
        }.resume()
        
    }
}

CodePudding user response:

There are many issues in the code.

The most significant ones are

  • In the struct userId and id are Int.
  • The JSON root object is an array, please note the starting [.
  • You don't update the model after receiving the data.

As you are using async/await anyway take full advantage of the pattern.

The JSON API returns posts, so how about to name the struct Post?

struct Post: Codable, Identifiable {
    let userId: Int
    let id: Int
    let title: String
    let body: String
}

struct ContentView : View {
    
    @State var posts = [Post]()
    
    var body : some View {
        List(posts) { post in
            Text(post.body)
        }
        .task {
            do {
                posts = try await loadData()
            } catch {
                print(error)
            }
        }
    }
    
    func loadData() async throws -> [Post] {
        
        let urlString = "https://jsonplaceholder.typicode.com/posts"
        let url = URL(string: urlString)!
        
        let (data, _) = try await URLSession.shared.data(for: URLRequest(url: url))
        return try JSONDecoder().decode([Post].self, from: data)
    }
}
  • Related