title: Asynchronous completion handling in a function with multiple closures/API requests in swift
body: <p>I just started developing in Swift, so im totally new to closures. I'm also new how to handle asynchronous API request.</p>
  
  <p>I have read a lot of similar question such as, <a href="https://stackoverflow.com/questions/26794701/how-to-get-data-to-return-from-nsurlsessiondatatask-in-swift">How to get data to return from NSURLSessionDataTask in Swift</a> and <a href="https://stackoverflow.com/questions/24647406/how-to-use-completionhandler-closure-with-return-in-swift">How to use completionHandler Closure with return in Swift?</a>. These helped me, but my problem it a little bit different.</p>
  
  <p>In my function I want to first make a API request to get a JSON payload. With some data in this JSON payload I want to make multiple other API request. In this case, I will for each of API request receive a JSON payload, where I want to store some of the data in my own JSON data structure. </p>
  
  <p>The problem is that, for every multiple API request I make I can only return part of my own JSON data in my CompletionHandler - This is only way to return data when making an API request using a closure, as far as I understand.</p>
  
  <p>So instead of getting multiple completion handlers, when calling my function, I just want to receive a single.</p>
  
  <p>The thing is I dont know to how to completion handling several closures in a function, in this case two closures.</p>
  
  <p>I have posted my code below - I know its quite long and maybe not that clean.
  However, the point is that when im updating offers to my storeDict this will be empty, due to the offers dict array is getting its information from inside the second closure. This is shown at the bottom of the function.</p>
  
  <pre><code>   func getOffersFromWishList(offerWishList: [String], latitude: Double, longitude: Double, radius: Int, completionHandler: ([NSDictionary] -&gt; Void)) {
  
          var master: [NSDictionary] = []
  
          var nearby_params: NSDictionary = ["r_lat": latitude, "r_lng": longitude, "r_radius": radius]
          //println(nearby_params)
          var store_id_list: [String] = []
  
  
          // Get all store_ids for store which are nearby (Radius determines how nearby)
          singleton_eta.api("/v2/stores", type: ETARequestTypeGET, parameters: nearby_params, useCache: true, completion: { (response, error, fromCache) -&gt; Void in
  
              if error == nil {
  
                  let json = JSON(response)
                  storeArray = json.arrayValue
                  //println(storeArray)
  
                  for store in storeArray {
  
                      var storeDict = [String: AnyObject]()
                      var metaData = [String: String]()
                      var offers: [NSDictionary] = []
  
                      let name = store["branding"]["name"].stringValue
                      let store_id = store["id"].stringValue
                      let street = store["street"].stringValue
                      let city = store["city"].stringValue
                      let zip_code = store["zip_code"].stringValue
                      let dealer_id = store["dealer_id"].stringValue
                      let logo = store["branding"]["logo"].stringValue
  
                      metaData = ["name": name, "store_id": store_id, "street": street, "city": city, "zip_code": zip_code, "dealer_id": dealer_id, "logo": logo]
  
                      store_id_list.append(store_id)
  
                      //println("Butiks ID: \(store_id)")
  
                      var offset = 0
                      let limit = 100
  
                      // Loop through the offers for the specific store id - only possible to request 100 offers each time
                      // A while loop would be more suitable, but I dont know when to stop, as the length of the offerArray can not be counted as it is cant be accessed outside of the closure.
                      for x in 1...2 {
  
                          var store_params: NSDictionary = ["store_ids:": store_id, "limit": limit, "offset": offset]
                          println(store_params)
                          // Get offers for a specific store_id
                          singleton_eta.api("/v2/offers", type: ETARequestTypeGET, parameters: store_params, useCache: true, completion: { (response, error, fromCache) -&gt; Void in
  
                              if error == nil {
  
                                  offerArray = JSON(response).arrayValue
                                  //println( "TypeName0 = \(_stdlib_getTypeName(offerArray))")
  
                                  //Loop through the recieved offers
                                  for of in offerArray {
  
                                      let name = of["branding"]["name"].stringValue
                                      let dealer_id = of["dealer_id"].stringValue
                                      let heading = of["heading"].stringValue
                                      let description = of["description"].stringValue
                                      let price = of["pricing"]["price"].stringValue
                                      let image = of["images"]["view"].stringValue
  
  
                                      //println(heading)
  
                                      // Loop through our offerWishList
                                      for owl in offerWishList {
  
                                          let headingContainsWish = (heading.lowercaseString as NSString).containsString(owl.lowercaseString)
  
                                          // Check if offer match with our wish list
                                          if(headingContainsWish) {
  
                                              // Save neccesary meta data about each offer to a tuple array
                                              var offer = Dictionary&lt;String, String&gt;()
                                              offer = ["name": name, "dealer_id": dealer_id, "heading": heading, "description": description, "price": price, "image": image, "offerWishItem": owl]
  
                                              offers.append(offer)
  
  
                                          }
  
                                      }
  
                                  }
  
  
                              }
  
                          })
                          //println(storeDict)
                          offset = offset + limit + 1
  
                      }
  
                      storeDict.updateValue(metaData, forKey: "meta_data")
                      storeDict.updateValue(offers, forKey: "offers")  // offers is empty due to its appending inside the closure
                      master.append(storeDict)
  
                  }
               completionHandler(master)
  
              }
  
              else {
                  println(error)
              }
  
  
          })
  
      }
  </code></pre>
  
  <p>Calling the above function</p>
  
  <pre><code>getOffersFromWishList(offerWishList, latitude, longitude, radius) { (master) -&gt; Void in
         println(master)
      }
  </code></pre>
  
  <p>This is what the master will print when calling the function, where offers is empty.</p>
  
  <pre><code>{
  "meta_data" =     {
      city = "Kongens Lyngby";
      "dealer_id" = d8adog;
      logo = "https://d3ikkoqs9ddhdl.cloudfront.net/img/logo/default/d8adog_3qvn3g8xp.png";
      name = "d\U00f8gnNetto";
      "store_id" = d2283Zm;
      street = "Kollegiebakken 7";
      "zip_code" = 2800;
  };
  offers =     (
  );
  }
  { 
    ...
  }
  </code></pre>
  
  <p>So my questions, what is the proper way to return data from the second closure to the first closure inside a function? Or am I doing this in the completely wrong way? 
  The thing is, I need all this data for a tableview and therefore need all the data at once.</p>