json file : https://dl.dropboxusercontent.com/s/ypknurke7e3062x/swiftuasyncimage.json?dl=0
ContentView.swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | // // ContentView.swift // swiftuidev15ios // // Created by Cairocoders // import SwiftUI struct ContentView: View { @ObservedObject var vmodel = ViewModel() var body: some View { NavigationView { ScrollView { if vmodel.isFetching { ProgressView() } VStack { ForEach(vmodel.courses) { asycimage in let url = URL(string: asycimage.imageUrl) AsyncImage(url: url) { image in image.resizable() .scaledToFill() } placeholder: { ProgressView() } Text(asycimage.name) } } } .navigationTitle( "AsyncImage Loading" ) .task { await vmodel.fetchData() } .navigationBarItems(trailing: refreshButton) } } private var refreshButton: some View { Button { Task.init { vmodel.courses.removeAll() await vmodel.fetchData() } } label: { Text( "Refresh" ) } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | // // ViewModel.swift // swiftuidev15ios // // Created by Cairocoders // import SwiftUI class ViewModel: ObservableObject { @Published var isFetching = false @Published var courses = [Course]() @Published var errorMessage = "" @MainActor func fetchData() async { guard let url = URL(string: urlString) else { return } do { isFetching = true let (data, response) = try await URLSession.shared.data(from: url) if let resp = response as? HTTPURLResponse, resp.statusCode >= 300 { self.errorMessage = "Failed to hit endpoint with bad status code" } self.courses = try JSONDecoder().decode([Course].self, from: data) isFetching = false } catch { isFetching = false print( "Failed to reach endpoint: \(error)" ) } } } struct Course: Decodable, Identifiable { let id: Int let name, link, imageUrl: String } |