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
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()
    }
}
ViewModel.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
//
//  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
}

Related Post