Search code examples
swiftalamofireglobalcompletionhandler

Alamofire access append data to global variable


I am having some trouble doing an Alamofire call and appending the JSON data to a global array, and I'm really starting to stress.

I understand that when doing API calls it is done in an asynchronous thread. However after doing research on the matter, I have followed what the recommendations are but I'm getting lost because in everyones example they only print the data, and that works, but when I try to append the data to an array I'm still getting a count of 0.

class SomeClass: UIViewController {
    var categories = [Int]()
    @IBOutlet var labels: [UILabel]!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.getJSON() { response in 
            self.populateArray(json: response)
        }

        //This prints 0 :( 
        print("Size: \(categories.count)")
        var count = 1
        for lbl in labels {
            for var i in 0..<categories.count {
                //Obviously this never computes so they all are black instead of some being red
                lbl.tintColor = count == categories[i] ? UIColor.Red : UIColor.Black
        }
    }

    public func getJSON(completionhandler: @escaping (JSON) -> ()) () {
        Alamofire.request("some url").responseJSON { response in 

        switch response.result {
            case .success:
                let jsonData = JSON(data: response.data!)
                completionHandler(jsonData)
            case .failure(let error):
                print(error)
            }
       }
   }

   public func populateArray(json: JSON) -> () {
        //JSON still prints fine
        print(json)
        for (index, subJson):(String, JSON) in json {
            //Again, prints fine
            print(subJson["catID"].int!)
            self.categories.append(subJson["catID"].ind!)
        }
    }
}

Does anyone know what I am doing wrong? or if it is achievable in the first place, which if not, is there an alternative to achieve what I am after?

Many Thanks.


Solution

  • If you want that code to execute straight after getJson then you need to put that code inside the closure.

    self.getJSON() { response in 
    
        self.populateArray(json: response)
    
        print("Size: \(categories.count)")
    
        var count = 1
    
        for lbl in labels {
    
            for var i in 0..<categories.count {
    
                lbl.tintColor = (count == categories[i] ? UIColor.Red : UIColor.Black)
            }
        }
    }