How to wait for async calls to finish

I am running three API calls using the Spotify API, in order to get the following data and store them into my Artist object:

  1. The artist.
  2. That artist's albums.
  3. Tracks of each albums of the artist.

Once they are done, I would like to pass the object to a different view controller. It looks something like this: (If could post all the NSURLSession code in there if necessary)

func getArtist(artistName) {

func getAlbums(artistIdString) {
 a = Album
 for album in Artist.albumsArray {

func getTracks (albumIdString) {
 t = Track
 for album in Artist.albumsArray {
  if idString == albumIdString {

func passArtist {  
 DataStore.sharedInstance().Artist = Artist


  • In the callback function/block (or completion handler in Apple's term) of NSURLSession (or NSURLSessionDataTask), run a check function against the current Artist object and see if all the 3 required elements were there (and if so, make a call to passArtist).

    No matter how the finishing order is, it will eventually call the passArtist once it's done fetching 3 elements if you did so.

    Here's a simple example to demonstrate the idea in Objective-C (as OP requested):

    - (void)getArtistDataWithRequest:(NSURLRequest *)request
        NSURLSession         *session = [NSURLSession sharedSession];
        NSURLSessionDataTask *task    = [session dataTaskWithRequest:request
                                                   completionHandler:^(NSData        *data,
                                                                       NSURLResponse *response,
                                                                       NSError       *error)
                                             if (error)
                                                 // Something went wrong, fallback.
                                                 NSLog(@"An error occurred: %@", error.localizedDescription);
                                                 // You could use some error handler e.g.:
                                                 // [self connectionDidFailWithError:error];
                                             else if (response)
                                                 // Seems working, moving forward.
                                                 [self connectionDidReceiveSpotifyServerResponse:response
        [task resume];
    - (void)connectionDidReceiveSpotifyServerResponse:(NSURLResponse *)aResponse
                                              andData:(NSData *)aResponseData
        // Do what you want here with the data you get, either it's album, track,
        // or whatever.
        // Assuming your "Artist" property is named "myArtist", and the "Artist"
        // class has a method to process the data you get from Spotify API:
        [_myArtist handleArtistData:aResponseData];
        // Now check your Artist object's element with another method. e.g.:
        if ([_myArtist isLoadingComplete])
            // Done loading the object, pass it to view controller.
        // Not yet done, do nothing for now.

    This is just one solution. There are many ways to achieve what you wanted once you get the idea.