Loading View on API call

I have a Loading view saying "Please wait" that I want to be presented until the data from the API comes back. However, self.showLoading = false is executed even before store.getHomeItems() is finished.

How can I do it ?

struct HomeView: View {
  @State var showLoading = false
  ...

  if (self.showLoading == true) {
      LoadingView()
  } else {
      //my content
  }
   ...
  ScrollView {
    //my scroll content
  }
  .onAppear {
      self.showLoading = true
      DispatchQueue.main.async {
          store.getHomeItems()
      }
      self.showloading = false
    ...
  }

I also dont know if I can call Dispatch on my HomeView, since my API layer has also an another DispatchQueue.

URLSession.shared.dataTask(with: url) { (data, _, _) in
      guard let data = data else { return }
       
      let myItems = try! JSONDecoder().decode([ItemModel].self, from: data)
     DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
        completion(myItems)
      }   
    }
    .resume()

Thank you

Answered by workingdogintokyo in 695904022

Make your getHomeItems() with a closure when done, and try something like this:

        .onAppear {
            self.showLoading = true
            DispatchQueue.main.async {
                store.getHomeItems() { _ in   // <--- here
                    self.showloading = false  // <--- here
                }
            }
          ...
        }
Accepted Answer

Make your getHomeItems() with a closure when done, and try something like this:

        .onAppear {
            self.showLoading = true
            DispatchQueue.main.async {
                store.getHomeItems() { _ in   // <--- here
                    self.showloading = false  // <--- here
                }
            }
          ...
        }

If I do this way I will have "Argument passed to call that takes no arguments" I also tried: store.getHomeItems() { () -> in

This is the signature for the method: func getHomeItems() { ... }

Loading View on API call
 
 
Q