article

Monday, November 22, 2021

SwiftUI AsyncImage Loading Fetching Data with Asnc and Await

SwiftUI AsyncImage Loading Fetching Data with Asnc and Await

json file : https://dl.dropboxusercontent.com/s/ypknurke7e3062x/swiftuasyncimage.json?dl=0

ContentView.swift
 
//
//  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()
    }
}
ViewModel.swift
 
//
//  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 {
        let urlString = "https://dl.dropboxusercontent.com/s/ypknurke7e3062x/swiftuasyncimage.json?dl=0"

        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
}

Related Post