title: How to wait for an API request to finish before storing data from function callback?
body: <p>In a personal project of mine, I have created an API caller to retrieve a user's saved tracks from the Spotify API. The Spotify endpoint which I am using has a limit (maximum of 50 tracks per request) as well as an offset (starting index of first track in request), which is why I decided to use a FOR loop to get a series of track pages (each 50 tracks) and append them to a global array. The data is loaded from the main thread, and while the data is being requested, I display a child view controller with a spinner view. Once the data request has completed, I remove the spinner view, and transition to another view controller (passing the data as a property).</p>
  <p>I have tried many things, but the array of tracks is always empty following the API request. I have a feeling it has to do with the synchronicity of my request, or maybe its possible that I'm not handling it correctly. Ideally, I would like to wait until the request from my API finishes, then append the result to the array. Do you have any suggestions on how I could solve this? Any help is much appreciated!</p>
  <pre><code>func createSpinnerView() {
  
      let loadViewController = LoadViewController.instantiateFromAppStoryboard(appStoryboard: .OrganizeScreen)
      add(asChildViewController: loadViewController)
  
      DispatchQueue.main.async { [weak self] in
          if (self?.dropdownButton.dropdownLabel.text == &quot;My saved music&quot;) {
              self?.fetchSavedMusic() { tracksArray in
                  self?.tracksArray = tracksArray
              }
          }
          ...
          self?.remove(asChildViewController: loadViewController)
          self?.navigateToFilterScreen(tracksArray: self!.tracksArray)
      }
  }
  
  private func fetchSavedMusic(completion: @escaping ([Tracks]) -&gt; ()) {
      let limit = 50
      var offset = 0
      var total = 200
      for _ in stride(from: 0, to: total, by: limit) {
          getSavedTracks(limit: limit, offset: offset) { tracks in
              //total = tracks.total
              self.tracksArray.append(tracks)
          }
          print(offset, limit)
          offset = offset + 50
      }
      completion(tracksArray)
  }
  
  private func getSavedTracks(limit: Int, offset: Int, completion: @escaping (Tracks) -&gt; ()) {
      APICaller.shared.getUsersSavedTracks(limit: limit, offset: offset) { (result) in
          switch result {
          case .success(let model):
              completion(model)
              print(&quot;success&quot;)
          case .failure(let error):
              print(&quot;Error retrieving saved tracks: \(error.localizedDescription)&quot;)
              print(error)
          }
      }
  }
  
  private func navigateToFilterScreen(tracksArray: [Tracks]) {
      let vc = FilterViewController.instantiateFromAppStoryboard(appStoryboard: .OrganizeScreen)
      vc.paginatedTracks = tracksArray
      show(vc, sender: self)
  }
  </code></pre>