ContentView.swift
// // ContentView.swift // SwiftUIProject // // Created by Cairocoders // import SwiftUI struct ContentView: View { @ObservedObject var viewModel = ContentViewModel() var body: some View { NavigationView { VStack { List(viewModel.items, id: \.id) { item in VStack(alignment: .leading) { Text(item.title) Text(item.completed.description) .font(.system(size: 11)) .foregroundColor(.gray) } } .listStyle(GroupedListStyle()) }.onAppear(perform: { viewModel.fetchData() }) .navigationBarTitle("Fetch JSON Datas") } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }ViewModel.swift
// // ViewModel.swift // SwiftUIProject // // Created by Cairocoders // import SwiftUI class ContentViewModel: ObservableObject { @Published var items = [Model]() func fetchData() { let api = "https://jsonplaceholder.typicode.com/todos" guard let url = URL(string: api) else { return } URLSession.shared.dataTask(with: url) { (data, response, error) in do { if let data = data { let result = try JSONDecoder().decode([Model].self, from: data) DispatchQueue.main.async { self.items = result } } else { print("No data") } } catch (let error) { print(error.localizedDescription) } }.resume() } }Model.swift
// // Model.swift // SwiftUIProject // // Created by Cairocoders // import SwiftUI struct Model: Decodable { let id: Int let userId: Int let title: String let completed: Bool }