Search code examples
arraysjsonswiftgoogle-places-apigoogle-maps-sdk-ios

Swift Array will not populate with JSON Data


The issue I am facing is that i am unable to populate the empty array with the JSON Data and can not find a similar problem asked on StackOverflow.

Within the function itself I can get the empty array and populate the array within the function. Then call a print function within the downloadRestaurantDetails function to see the information i had parsed.

But I am unable to populate the original empty array that is outside of the function so that I can get the populated array and use it in a different function.

import UIKit
import GoogleMaps
import Alamofire
import SwiftyJSON

class ViewController: UIViewController {

var placeIDArray = [String]()
var placeID: String!

override func viewDidLoad() {
    super.viewDidLoad()

    downloadRestaurantDetails { () -> () in

    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


func downloadRestaurantDetails(completed: DownloadComplete) {
    //url is acquired through a file created for global variables
    Alamofire.request(.GET,url).responseJSON { (response) -> Void in
        if let value  = response.result.value {
            let json = JSON(value)

            //Acquire All place_id of restaurants
            if let results = json["results"].array {
                for result in results {
                    if let allPlace_ID = result["place_id"].string {
                        //Add All place_id's into an array
                        self.placeIDArray.append(allPlace_ID)
                    }

                }
            }
        }

    // i call this method to check and see if there is anything placed in the array outside of the downloadRestaurantDetails method.

    func check() {
    if self.placeIDArray.count > 1 {
        print(self.placeIDArray)

    } else {
        print(self.placeIDArray.count)
    }
}

To conclude, the issue I would like to solve,

  • I would like to parse the place_id and place the resulting strings in the placeIDArray. I am able to parse the data and store the values inside of the placeIDArray within the function. I am not able to store the parsed data in the empty array out of the function. I had thought that by using self.placeIDArray the parsed data would be assigned to the array. but it doesn't seem to be the case.

Solution

  • downloadRestaurantDetails is asynchronous. So if you call check right after calling the above function, then it's possible (and very likely) that the JSON has not been fetched yet and so placeIDArray has not been filled yet. You must call it in the callback, because that's when the data has actually been downloaded and filled into the array.

    So:

    1. Add the callback after the data has been set:

      func downloadRestaurantDetails(completed: DownloadComplete) {
          //url is acquired through a file created for global variables
          Alamofire.request(.GET,url).responseJSON { (response) -> Void in
              if let value  = response.result.value {
                  let json = JSON(value)
      
                  //Acquire All place_id of restaurants
                  if let results = json["results"].array {
                      for result in results {
                          if let allPlace_ID = result["place_id"].string {
                              //Add All place_id's into an array
                              self.placeIDArray.append(allPlace_ID)
      
                          }
      
                      }
                      // !!! Call the callback:
                      completed()
                  }
      }
      
    2. Then you can call check inside the callback:

      override func viewDidLoad() {
          super.viewDidLoad()
      
          downloadRestaurantDetails { () -> () in
              // The array is now filled.
              self.check()
          }
      }