title: Swift URLSession running asynchronously so it doesn't register in time for onAppear to add data to View
body: <p>I am trying to call an API and then display that data in my view in Swift. I can successfully make the API call and get the data back, but I am having trouble displaying this data. As seen in the below code, my load function moves on before it is done decoding the data and saving it in a self variable.</p>
  <p>Here is the load function:</p>
  <pre><code>func loadRestaurant(completed:@escaping () -&gt; ()) {
      print(&quot;loaded started&quot;)
      //print(self.restaurants)
      guard let url = URL(string: &quot;http://127.0.0.1:8000/api/restaurant/&quot;) else {
          print(&quot;api is down&quot;)
          return
      }
      
      var request = URLRequest(url: url)
      request.httpMethod = &quot;GET&quot;
      request.addValue(&quot;application/json&quot;, forHTTPHeaderField: &quot;Accept&quot;)
      request.addValue(&quot;Basic a21jY2xlbm46ZGV4SVNkZXgzMTQ=&quot;, forHTTPHeaderField: &quot;Authorization&quot;)
      print(&quot;request created&quot;)
      URLSession.shared.dataTask(with: request) {data, response, error in
          if let data = data {
  //
              if let response = try? JSONDecoder().decode([Restaurant].self, from: data) {
                  print(&quot;decoder run&quot;)
                  DispatchQueue.main.async {
                      self.restaurants = response
                      //print(self.restaurants)
                      queue.async {
                          Thread.sleep(forTimeInterval: Double.random(in: 0...2))
                          completed()
                      }
                  }
                  
                  return
              } else {
                  print(&quot;response decoding failed&quot;)
              }
              
          }
      }.resume()
  }
  </code></pre>
  <p>Here is how I am trying to display in in the view:</p>
  <pre><code>@State var restaurants = [Restaurant]()
  let queue = DispatchQueue(label: &quot;concurrentQueue&quot;, attributes: .concurrent)
  var body: some View {
      
      ForEach(restaurants, id: \.id) {item in
          HStack {
  
              Text(item.name)
              Spacer()
  
          }
      }.onAppear(perform: {
          print(&quot;before running function&quot;)
          loadRestaurant(completed: {
              print(&quot;restaurants: \(restaurants)&quot;)
              
          })
          
          print(&quot;after running function&quot;)
          
  })
  }
  </code></pre>
  <p>When I run the program, the order of the print statements goes like this:</p>
  <p>before running function</p>
  <p>loaded started</p>
  <p>request created</p>
  <p>after running function</p>
  <p>decoder run</p>
  <p>restaurants: <em>RESTAURANTS DATA</em></p>
  <p>As you can see, the decoder and the final display of the data (where it is saved to the self.restaurants variable) runs after the .onAppear finishes. So, there is no data to be loaded into the display. Does anyone have any ideas on how to fix this? I have tried to add a closure (see the completed() function), but it seems like there is no way to re-draw the view even after the closure function is run. Thank you for your help.</p>